TeslaMate v4.4.0 Docker Compose 部署指南

TeslaMate v4.4.0 官方 Docker Compose 编排部署实录:四服务镜像选型、显式项目名与固定网段的 compose 全文、首次启动迁移验证、Grafana 首登与 24 张仪表盘确认、特斯拉账号绑定流程,含 Created 遗留、28P01 密码错误、Basic Auth 401 等排障实录。

TeslaMateTeslaMate数据采集2026/11/01

TeslaMate v4.4.0 Docker Compose 部署指南

目标:在一台常驻在线的服务器上,用官方 Docker Compose 编排把 TeslaMate v4.4.0 完整跑起来(TeslaMate 主服务 + PostgreSQL 18 + Grafana 13 + 可选 Mosquitto MQTT),完成数据落库、Web 管理界面与 24 张预置仪表盘的可用性验证,并沉淀部署全程的排障实录。已在 Ubuntu 26.04.1 LTS / Docker 29.9.2 / Docker Compose v5.6.1 实测通过;车辆绑定环节依赖真实特斯拉账号凭据,本篇以官方流程呈现并明确标注,其余环节均为实测回显。

一、环境信息

本篇所有命令与回显均在以下环境实测,输出逐行照抄:

  • 操作系统:Ubuntu 26.04.1 LTS(x86_64,内核 7.0.0-38-generic)
  • Docker:Docker version 29.9.2, build a82e528;Docker Compose version v5.6.1
  • TeslaMate:v4.4.0(官方镜像 teslamate/teslamate:4.4.0;官方最新稳定版截至 2026-11-01 仍为 v4.4.0,GitHub Releases atom feed 实查,2026-10-23 发布,无更新版本)
  • 数据库:PostgreSQL 18.6(postgres:18-trixie,实测 SELECT version(); 回显 PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2) on x86_64-pc-linux-gnu)
  • 可视化:Grafana 13.2.4(teslamate/grafana:latest,实测 /api/health 回显 "version": "13.2.4")
  • MQTT:eclipse-mosquitto 2(eclipse-mosquitto:2,可选组件)
  • 项目目录:/opt/teslamate/(compose 文件所在目录)
  • 端口规划:TeslaMate Web 8128、Grafana 8135(宿主机侧),容器内分别为 4000 与 3000;数据库 5432 与 MQTT 1883 仅在内部网络暴露
  • 编排项目名:teslamate-4.4.0-stack(写进 compose 文件 name: 字段;Docker Compose 会把项目名中的 . 规范化为 -,实际项目名为 teslamate-4-4-0-stack,docker compose ls 可验证)
  • 容器命名:teslamate-4.4.0-app、teslamate-4.4.0-db、teslamate-4.4.0-grafana、teslamate-4.4.0-mosquitto

💡 说明:本篇部署载体是 Docker Compose 一键编排——这也是官方文档唯一给出完整模板的「一等公民」部署形态(其余 Debian/FreeBSD/Unraid 手动安装均被官方标注为不受支持方法)。组件架构与选型背景见 《TeslaMate v4.4.0 介绍与选型指南》,环境变量逐项解释见本专栏 《TeslaMate v4.4.0 配置参数详解》篇,命令行工具详见 《TeslaMate v4.4.0 常用 CLI 命令与工具详解》篇。

二、镜像选型说明

TeslaMate 官方编排涉及四个镜像,选型依据如下:

服务镜像版本选型说明
teslamateteslamate/teslamate4.4.0(锁定)官方应用镜像,含 Elixir/Erlang 运行时与预编译 release;版本显式锁定 4.4.0 而不用 latest,保证升级由自己控制(官方文档示例用 latest,生产建议锁版本)
databasepostgres18-trixie(Debian 13 trixie 底座)官方模板指定版本;TeslaMate 要求启用 cube/earthdistance 扩展(首次启动自动创建),实测 18.6 通过兼容性检查(启动日志 PostgreSQL version 18.6 is compatible (18.x series).)
grafanateslamate/grafanalatestTeslaMate 官方维护的 Grafana 定制镜像(基于 Grafana 13.2.4),启动时自动导入全部预置仪表盘并自动配置 PostgreSQL 数据源,普通 grafana/grafana 镜像做不到这两点
mosquittoeclipse-mosquitto2官方 Eclipse 基金会 MQTT Broker 镜像,官方模板以 /mosquitto-no-auth.conf(免认证配置)启动,仅在内网使用

💡 技术拓展:Grafana 数据源接入有「预置镜像」与「手工配置」两条路线。| 路线 | 特点 | 适用场景 | |---|---|---| | TeslaMate 定制镜像(本篇所用) | 启动即自动导入 24 张仪表盘 + 自动配置 PostgreSQL 数据源 | 想开箱即用的大多数用户 | | 原版 grafana/grafana 镜像 | 需手动添加 PostgreSQL 数据源、逐张导入官方 JSON 仪表盘 | 需要自定义仪表盘集合或共享既有 Grafana 实例 |

本篇采用官方定制镜像,理由是与 TeslaMate 数据库结构版本联动升级,仪表盘与数据模型始终保持匹配。

镜像架构支持:amd64(Intel/AMD 64 位)与 aarch64(ARM 64 位);armv7 不再支持(树莓派 3 及更早的 32 位系统不可用,官方安装页明确说明)。

三、前置条件

部署前逐项确认以下条件,全部满足后再进入部署步骤:

  1. 常驻在线的机器:TeslaMate 依赖持续采集,停机即丢数据(特斯拉 API 不提供历史回补)。官方要求至少 1 GB 内存(推荐 2 GB 以上)、能访问 tesla.com 相关域名;
  2. Docker 与 Docker Compose v2:验证命令与实测回显:
docker --version && docker compose version
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
  1. 端口未被占用:本篇用 8128(TeslaMate Web)与 8135(Grafana),部署前确认空闲:
ss -ltn | grep -E ':8128|:8135' || echo "ports free"
ports free
  1. 特斯拉账号令牌的准备(可延后):车辆绑定需要 Tesla API 的 access token 与 refresh token。TeslaMate 不内置令牌生成功能(官方解释:生成逻辑需频繁跟进特斯拉改动),官方推荐用独立工具 Tesla Auth(0.13.0+)或 iOS 端 Auth app for Tesla 生成。此步骤依赖真实特斯拉账号凭据,本机环境无真实账号,未做实测——其余所有部署与验证环节不依赖它,可先部署后绑定车辆;
  2. 出站网络:auth.tesla.com、owner-api.teslamotors.com、streaming.vn.teslamotors.com(443/TCP)、nominatim.openstreetmap.org(443/TCP)与 step.esa.int(80/TCP)为官方列明的必通出口。本机实测这些域名的连通由采集环节依赖,部署与本地验证不阻塞。

四、部署步骤

4.1 创建项目目录

所有部署产物收敛到一个目录,便于后续升级、备份与迁移:

mkdir -p /opt/teslamate/import && cd /opt/teslamate

import 子目录是 TeslaFi/apiscraper 历史数据导入目录(挂载进容器 /opt/app/import),暂不使用也要创建,避免 Docker 自动创建时归属 root 之外的权限混乱。

4.2 写入 docker-compose.yml

创建 /opt/teslamate/docker-compose.yml,内容如下(官方模板 + 本机适配:显式项目名、独立网段、锁版本、端口映射、时区;占位值已全部落为实测值):

name: teslamate-4.4.0-stack

networks:
  teslamate-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.56.0/24

services:
  teslamate:
    image: teslamate/teslamate:4.4.0
    container_name: teslamate-4.4.0-app
    restart: always
    environment:
      - ENCRYPTION_KEY=teslamate-demo-key-2026   # 加密特斯拉 API 令牌的密钥,生产请换成自己的长随机串
      - DATABASE_USER=teslamate
      - DATABASE_PASS=q1w2e3r4                    # 与 database 的 POSTGRES_PASSWORD 必须一致
      - DATABASE_NAME=teslamate
      - DATABASE_HOST=database
      - MQTT_HOST=mosquitto
      - PORT=4000
      - TZ=Asia/Shanghai
    ports:
      - 8128:4000
    volumes:
      - ./import:/opt/app/import
    cap_drop:
      - all

  database:
    image: postgres:18-trixie
    container_name: teslamate-4.4.0-db
    restart: always
    environment:
      - POSTGRES_USER=teslamate
      - POSTGRES_PASSWORD=q1w2e3r4
      - POSTGRES_DB=teslamate
      - TZ=Asia/Shanghai
    volumes:
      - teslamate-db:/var/lib/postgresql

  grafana:
    image: teslamate/grafana:latest
    container_name: teslamate-4.4.0-grafana
    restart: always
    environment:
      - DATABASE_USER=teslamate
      - DATABASE_PASS=q1w2e3r4
      - DATABASE_NAME=teslamate
      - DATABASE_HOST=database
      - GF_SECURITY_ADMIN_PASSWORD=q1w2e3r4
      - TZ=Asia/Shanghai
    ports:
      - 8135:3000
    volumes:
      - teslamate-grafana-data:/var/lib/grafana

  mosquitto:
    image: eclipse-mosquitto:2
    container_name: teslamate-4.4.0-mosquitto
    restart: always
    command: mosquitto -c /mosquitto-no-auth.conf
    # ports:
    #   - 1883:1883
    volumes:
      - mosquitto-conf:/mosquitto/config
      - mosquitto-data:/mosquitto/data

volumes:
  teslamate-db:
  teslamate-grafana-data:
  mosquitto-conf:
  mosquitto-data:

逐项说明关键差异(与官方模板对照):

  • name: teslamate-4.4.0-stack:显式编排项目名(官方模板无此项,默认取目录名)。多套 compose 栈共存的机器上必须显式命名,否则同目录名项目会互相覆盖;docker compose down 只会操作本项目名下的服务,不会误伤他人;
  • networks + subnet: 10.89.56.0/24:显式固定网段。Docker 默认从 172.17-172.31 池分配,多栈环境易冲突;10.89.56.0/24 为部署前查空的网段;
  • container_name:四个服务显式命名,docker logs/docker exec 时可直接引用,不必带项目前缀;
  • ENCRYPTION_KEY:用于加密特斯拉令牌的密钥,一旦产生数据就不可更换(换了旧令牌解不开);本篇演示落 teslamate-demo-key-2026,生产请用 openssl rand -base64 48 生成;
  • DATABASE_PASS 与 POSTGRES_PASSWORD:两处必须一致(本篇 q1w2e3r4),不一致会触发 FATAL 28P01 (invalid_password) 死循环(实测见 11.2 节);
  • TZ=Asia/Shanghai:让日志与统计数据时间落在本时区(官方变量表:用于建立本地时区);
  • PORT=4000:容器内 Web 端口,ports: 8128:4000 把宿主机 8128 映射进去;
  • GF_SECURITY_ADMIN_PASSWORD=q1w2e3r4:Grafana 管理员密码预设。官方模板不带此项(默认 admin/admin 首次登录强制改密),预设后首次登录即用 admin/q1w2e3r4;
  • cap_drop: [all]:官方模板自带的安全加固,丢弃容器全部 Linux capabilities,最小权限运行;
  • mosquitto 的 ports 保持注释:MQTT 1883 仅在内部网络供 TeslaMate 连接;需要 Home Assistant 等外部系统订阅时再放开并加认证。

4.3 启动编排栈

cd /opt/teslamate && docker compose up -d

实测回显(数据库与 Grafana 已在跑时补拉主服务的形态;全新环境四行均为 Pulling/Created/Starting/Started):

 Container teslamate-4.4.0-db Running 
 Container teslamate-4.4.0-grafana Running 
 Container teslamate-4.4.0-mosquitto Running 
 Container teslamate-4.4.0-app Starting 
 Container teslamate-4.4.0-app Started 

首次 up -d 会依次拉取四个镜像。本机拉取 teslamate/teslamate:4.4.0 等官方镜像直连 Docker Hub 即可完成(⚠️ 网络说明:Docker 守护进程已配置 HTTP 代理 192.168.1.62:7897,拉取慢时该代理自动生效;实际发生降级时按「官方源 → 国内源 → 代理」链路记录)。当前实测下载渠道:官方 Docker Hub 直连可用。

4.4 验证编排状态

docker compose ps

实测回显:

NAME                        IMAGE                       COMMAND                  SERVICE     CREATED          STATUS          PORTS
teslamate-4.4.0-app         teslamate/teslamate:4.4.0   "tini -- /bin/dash /…"   teslamate   15 minutes ago   Up 7 minutes    0.0.0.0:8128->4000/tcp, [::]:8128->4000/tcp
teslamate-4.4.0-db          postgres:18-trixie          "docker-entrypoint.s…"   database    15 minutes ago   Up 15 minutes   5432/tcp
teslamate-4.4.0-grafana     teslamate/grafana:latest    "/run.sh"                grafana     15 minutes ago   Up 15 minutes   0.0.0.0:8135->3000/tcp, [::]:8135->3000/tcp
teslamate-4.4.0-mosquitto   eclipse-mosquitto:2         "/docker-entrypoint.…"   mosquitto   15 minutes ago   Up 15 minutes   1883/tcp

四个服务全部 Up,端口映射符合预期(8128→4000、8135→3000,其余仅内网)。

4.5 观察首次启动日志(数据库迁移)

TeslaMate 主服务首次启动时自动执行数据库迁移(建全部表结构),无需手工跑迁移命令:

docker logs teslamate-4.4.0-app 2>&1 | tail -12

实测回显(节选,迁移行有省略):

2026-11-01 11:34:02.882 [info] No tzdata release files found in custom data dir. Copying release file from tzdata priv dir.
2026-11-01 11:34:02.921 [info] System Info: Erlang/OTP 29 (jit)
2026-11-01 11:34:02.921 [info] Version: 4.4.0
2026-11-01 11:34:02.937 [info] PostgreSQL version 18.6 is compatible (18.x series).
2026-11-01 11:34:02.955 [info] [proxy] read NOMINATIM_PROXY=nil
2026-11-01 11:34:02.955 [info] [proxy] NOMINATIM_PROXY unset -> fallback: no proxy
2026-11-01 11:34:02.965 [info] Running TeslaMateWeb.Endpoint with cowboy 2.20.0 at :::4000 (http)
2026-11-01 11:34:02.965 [info] Access TeslaMateWeb.Endpoint at http://localhost
2026-11-01 11:34:03.863 [info] MQTT connection has been established
2026-11-01 11:34:06.843 [info] tzdata release in place is from a file last modified Fri, 11 Sep 2026 22:36:31 GMT. Release file on server was last modified Wed, 28 Oct 2026 07:16:29 GMT.
2026-11-01 11:34:08.113 [info] Tzdata has updated the release from 2026d to 2026f

迁移阶段日志(首次启动必有,格式如下,本段为首次建库实测,create table 行做了节选):

2026-11-01 10:39:42.078 [info] == Running 20190330150000 TeslaMate.Repo.Migrations.CreateCar.change/0 forward
2026-11-01 10:39:42.078 [info] create table cars
2026-11-01 10:39:42.080 [info] create index cars_eid_index
2026-11-01 10:39:42.083 [info] == Migrated 20190330150000 in 0.0s
(后续各迁移逐条 Running/Migrated,此处省略)

判定要点:Version: 4.4.0、PostgreSQL version 18.6 is compatible、Running TeslaMateWeb.Endpoint、MQTT connection has been established 四行齐备即启动成功。

4.6 验证 Web 界面与 Grafana 可达

TeslaMate Web 管理界面验证(未绑车辆时根路径重定向到登录页):

curl -sI http://127.0.0.1:8128/ | grep -E 'HTTP|location'
HTTP/1.1 302 Found
location: /sign_in
curl -s -o /dev/null -w 'code=%{http_code}\n' http://127.0.0.1:8128/sign_in
code=200

Grafana 健康检查:

curl -s http://127.0.0.1:8135/api/health
{
  "database": "ok",
  "version": "13.2.4",
  "commit": "0e79aef9d91abf3bdadae9af15763029072fb45b"
}

数据库侧验证(表结构已迁移、扩展已启用):

docker exec teslamate-4.4.0-db psql -U teslamate -d teslamate -c "\dt"

实测回显(节选,15 张表全部列出):

                    List of tables
 Schema |          Name           | Type  |   Owner   
--------+-------------------------+-------+-----------
 public | addresses               | table | teslamate
 public | car_settings            | table | teslamate
 public | cars                    | table | teslamate
 public | charges                 | table | teslamate
 public | charging_processes      | table | teslamate
 public | drives                  | table | teslamate
 public | geofences               | table | teslamate
 public | import_file_checkpoints | table | teslamate
 public | import_rejections       | table | teslamate
 public | import_runs             | table | teslamate
 public | positions               | table | teslamate
 public | schema_migrations       | table | teslamate
 public | settings                | table | teslamate
 public | states                  | table | teslamate
 public | updates                 | table | teslamate
(15 rows)
docker exec teslamate-4.4.0-db psql -U teslamate -d teslamate -c "\dx"

实测回显(节选):

                                 List of installed extensions
     Name      | Version | Default version |   Schema   |                         Description                          
---------------+---------+-----------------+------------+--------------------------------------------------------------
 cube          | 1.5     | 1.5             | public     | data type for multidimensional cubes
 earthdistance | 1.2     | 1.2             | public     | calculate great-circle distances on the surface of the Earth
 plpgsql       | 1.0     | 1.0             | pg_catalog | PL/pgSQL procedural language
(3 rows)

cube 与 earthdistance 扩展由 TeslaMate 迁移自动创建,用于地理位置计算,无需手工安装。

4.7 Grafana 首次登录与仪表盘确认

浏览器打开 http://<服务器IP>:8135:

  • 本篇形态(预设了 GF_SECURITY_ADMIN_PASSWORD):账号 admin、密码 q1w2e3r4 直接登录成功;
  • 官方默认形态(未预设该变量):账号 admin、初始密码 admin,首次登录强制修改密码。

用 curl 实测登录与仪表盘清单(Grafana 13 的该镜像禁用了 HTTP Basic 认证,需走表单登录 API 取会话 Cookie——排障实录见 11.3 节):

curl -s -c /tmp/gf-cookie.txt -H 'Content-Type: application/json' \
  -d '{"user":"admin","password":"q1w2e3r4"}' http://127.0.0.1:8135/login
{"message":"Logged in","redirectUrl":"/"}
curl -s -b /tmp/gf-cookie.txt 'http://127.0.0.1:8135/api/search' \
  | python3 -c 'import json,sys; d=json.load(sys.stdin); print("count:",len(d)); [print(x["title"]) for x in d]'

实测回显(count: 27 为 3 个导航文件夹 + 24 个仪表盘;标题逐行照抄):

count: 27
Internal
Reports
TeslaMate
Battery Health
Charge Details
Charge Level
Charges
Charging Stats
Database Information
Drive Details
Drive Stats
Drives
Drives - Dutch tax
Efficiency
Home
Locations
Mileage
Overview
Projected Range
States
Statistics
Temperatures
Timeline
Trip
Updates
Vampire Drain
Visited

24 张仪表盘(Overview、Drives、Charges、Charging Stats、Efficiency、Mileage、Vampire Drain、Battery Health、Projected Range、Visited 等)由 teslamate/grafana 镜像启动时自动导入,无需手工导入 JSON。数据源亦已自动配置为 PostgreSQL(实测 /api/datasources 回显 "name":"TeslaMate","type":"grafana-postgresql-datasource","url":"database:5432","user":"teslamate","jsonData":{"database":"teslamate","postgresVersion":1500,"sslmode":"disable"})。

4.8 绑定特斯拉账号与车辆

⚠️ 本节依赖真实特斯拉账号凭据,本机环境无真实账号,未做实测;以下为官方文档(docs.teslamate.org/docs/installation/tokens)流程呈现,其余环节均已在前面各节实测。

  1. 用 Tesla Auth 工具(0.13.0+,macOS/Linux/Windows 均有发行版)或 iOS 端 Auth app for Tesla,以特斯拉账号登录生成 access token 与 refresh token;
  2. 浏览器打开 http://<服务器IP>:8128,自动跳转到 /sign_in 登录页(实测该页 200 可达);
  3. 在登录页粘贴 access token 与 refresh token,提交后 TeslaMate 注册车辆并开始采集;
  4. 回到 TeslaMate Web 界面 Settings → URLs,把 Web App URL 填为 http://<服务器IP>:8128、Dashboards URL 填为 http://<服务器IP>:8135,让界面与仪表盘互链双向可用;
  5. 打开 http://<服务器IP>:8135 任一仪表盘(如 Overview),车辆数据到位后图表开始呈现。

车辆绑定成功的验证命令(绑定后有回显数据):

docker exec teslamate-4.4.0-db psql -U teslamate -d teslamate -t -c "SELECT id, name, vid FROM cars;"

本机未绑定时实测返回 0 行(空结果),绑定真实车辆后此处会列出车辆记录。

五、数据持久化说明

四个 named volume + 一个 bind mount 构成全部持久化面:

卷/目录容器内路径内容丢失影响
teslamate-db/var/lib/postgresqlPostgreSQL 全部数据(车辆、行程、充电、轨迹)致命:所有历史数据丢失
teslamate-grafana-data/var/lib/grafanaGrafana 数据库与预置仪表盘仪表盘自定义修改丢失(预置面板会重新导入)
mosquitto-data/mosquitto/dataMQTT 持久化消息可忽略(状态主题实时发布)
mosquitto-conf/mosquitto/configMosquitto 配置可忽略(模板用内置免认证配置)
./import(bind)/opt/app/importTeslaFi/apiscraper 导入 CSV导入历史丢失

验证卷与数据落盘:

docker volume ls | grep teslamate
local     teslamate-4-4-0-stack_teslamate-db
local     teslamate-4-4-0-stack_teslamate-grafana-data
local     teslamate-4-4-0-stack_mosquitto-conf
local     teslamate-4-4-0-stack_mosquitto-data

💡 说明:volume 实际名称带项目名前缀 teslamate-4-4-0-stack_(Compose 规范:项目内资源自动加项目名前缀),这也是显式项目名带来的资源隔离效果。备份策略:pg_dump 逻辑备份(官方维护文档推荐 docker exec teslamate-4.4.0-db pg_dump -U teslamate teslamate > teslamate.bck),恢复用 psql 回灌;升级 PostgreSQL 大版本时用 pg_dumpall 全量导出再导入新库。

六、环境变量表

本篇只列部署必填与常用项;全量 40+ 变量(MQTT 细节、轮询间隔、Fleet API、导入配置等)逐项解释见本专栏《TeslaMate v4.4.0 配置参数详解》篇。

6.1 TeslaMate 主服务(teslamate)

变量必填本篇取值说明(官方默认)
ENCRYPTION_KEY✅teslamate-demo-key-2026加密特斯拉 API 令牌的密钥(无默认;产生数据后不可更换)
DATABASE_USER✅teslamate数据库用户名(与 database 服务 POSTGRES_USER 一致)
DATABASE_PASS✅q1w2e3r4数据库密码(与 POSTGRES_PASSWORD 一致)
DATABASE_NAME✅teslamate数据库名(与 POSTGRES_DB 一致)
DATABASE_HOST✅database数据库主机名(compose 服务名即 DNS 名)
MQTT_HOST✅*mosquittoMQTT Broker 主机名(*除非设 DISABLE_MQTT=true)
PORT—4000Web 界面监听端口(默认 4000)
TZ—Asia/Shanghai本地时区,影响日志与统计展示
VIRTUAL_HOST—未设生成站内 URL 的主机部分(默认 localhost;反代场景必设)
CHECK_ORIGIN—未设WebSocket 来源校验(默认 false;经反代访问时设 true 或域名列表)

6.2 数据库服务(database)

变量本篇取值说明
POSTGRES_USERteslamate超级用户名(TeslaMate 库属主)
POSTGRES_PASSWORDq1w2e3r4与 DATABASE_PASS 必须一致
POSTGRES_DBteslamate首次启动自动创建的库
TZAsia/Shanghai数据库日志时区
PGDATA(镜像内置)/var/lib/postgresql/18/docker实测 docker exec teslamate-4.4.0-db env 取得;卷挂载点为其父目录 /var/lib/postgresql

6.3 Grafana 服务(grafana)

变量本篇取值说明
DATABASE_USER / DATABASE_PASS / DATABASE_NAME / DATABASE_HOST同 TeslaMate定制镜像用它们生成 PostgreSQL 数据源配置
GF_SECURITY_ADMIN_PASSWORDq1w2e3r4Grafana 管理员密码预设;不设则默认 admin/admin 首登强改
TZAsia/Shanghai面板时间轴时区

七、配置参数说明

三处关键配置的关系与不可逆项,部署前务必理解:

  1. 数据库凭据三处一致:teslamate 服务的 DATABASE_PASS、database 服务的 POSTGRES_PASSWORD、grafana 服务的 DATABASE_PASS 三处必须同值。前两处不一致时 TeslaMate 报 FATAL 28P01 (invalid_password) 反复重连(实测见 11.2 节);Grafana 一处不一致时仪表盘查询全部报错(数据源连不上库);
  2. ENCRYPTION_KEY 一经使用不可更换:它加密的是入库的特斯拉 API 令牌。首启并绑定车辆后再换 key,旧令牌解密失败,车辆全部离线,只能重新生成令牌重新登录。空库阶段可随意改;
  3. 网段与项目名:10.89.56.0/24 为部署前查空的网段(多栈机器上必须显式固定,避免与既有网络冲突);项目名 teslamate-4.4.0-stack 决定 volume/网络前缀,定了就别再改,改了等于换一套卷。

八、配置文件挂载

本篇唯一的外部挂载是导入目录 bind mount:

    volumes:
      - ./import:/opt/app/import
  • 作用:把宿主机 /opt/teslamate/import 挂为容器 /opt/app/import(IMPORT_DIR 默认值即 ./import)。放入 TeslaFi 导出的按月 CSV 后重启 teslamate 服务,Web 界面会自动切换为导入表单;
  • 其余配置全部走环境变量注入,无配置文件需要手工编辑——这是官方模板的设计取向(Grafana 的数据源与仪表盘由定制镜像的 provisioning 机制在首次启动时自动写入 teslamate-grafana-data 卷);
  • Mosquitto 用镜像内置的 /mosquitto-no-auth.conf 免认证配置(command: 覆盖启动参数)。要自定义 Mosquitto(加认证、开监听)时,把写好的 mosquitto.conf bind mount 到 /mosquitto/config/mosquitto.conf 并改回默认 command:。

九、等价 docker run 命令

不用 Compose 时,以下四条命令等价复现本篇编排(逐一给出,仅作原理对照;实际部署仍建议 Compose——网络别名、卷声明、重启策略在 docker run 下要手工指定且分散):

# 0. 先建内部网络与持久化卷
docker network create --driver bridge --subnet 10.89.56.0/24 teslamate-net
docker volume create teslamate-db && docker volume create teslamate-grafana-data

# 1. 数据库
docker run -d --name teslamate-4.4.0-db --restart always \
  --network teslamate-net --network-alias database \
  -e POSTGRES_USER=teslamate -e POSTGRES_PASSWORD=q1w2e3r4 -e POSTGRES_DB=teslamate \
  -e TZ=Asia/Shanghai \
  -v teslamate-db:/var/lib/postgresql \
  postgres:18-trixie

# 2. TeslaMate 主服务
docker run -d --name teslamate-4.4.0-app --restart always \
  --network teslamate-net --network-alias teslamate \
  -p 8128:4000 \
  -e ENCRYPTION_KEY=teslamate-demo-key-2026 \
  -e DATABASE_USER=teslamate -e DATABASE_PASS=q1w2e3r4 \
  -e DATABASE_NAME=teslamate -e DATABASE_HOST=database \
  -e MQTT_HOST=mosquitto -e PORT=4000 -e TZ=Asia/Shanghai \
  --cap-drop ALL \
  -v /opt/teslamate/import:/opt/app/import \
  teslamate/teslamate:4.4.0

# 3. Grafana(定制镜像)
docker run -d --name teslamate-4.4.0-grafana --restart always \
  --network teslamate-net --network-alias grafana \
  -p 8135:3000 \
  -e DATABASE_USER=teslamate -e DATABASE_PASS=q1w2e3r4 \
  -e DATABASE_NAME=teslamate -e DATABASE_HOST=database \
  -e GF_SECURITY_ADMIN_PASSWORD=q1w2e3r4 -e TZ=Asia/Shanghai \
  -v teslamate-grafana-data:/var/lib/grafana \
  teslamate/grafana:latest

# 4. Mosquitto(可选)
docker run -d --name teslamate-4.4.0-mosquitto --restart always \
  --network teslamate-net --network-alias mosquitto \
  -v teslamate-mosquitto-conf:/mosquitto/config -v teslamate-mosquitto-data:/mosquitto/data \
  eclipse-mosquitto:2 mosquitto -c /mosquitto-no-auth.conf

要点:服务间用服务名互访依赖 --network-alias(Compose 下自动等于服务名);启动顺序上先起 database,TeslaMate 首连失败会自动重试(实测启动日志先报 tcp connect (database:5432): connection refused - :econnrefused 两行,随后连接成功完成迁移——这是正常现象,非故障)。

十、常用运维命令

# 查看四服务状态
cd /opt/teslamate && docker compose ps

# 跟踪主服务日志(实时)
docker logs -f teslamate-4.4.0-app

# 重启单个服务(改环境变量后必须 recreate,restart 不刷新 env)
cd /opt/teslamate && docker compose up -d --force-recreate teslamate

# 停止 / 启动整个栈
cd /opt/teslamate && docker compose stop
cd /opt/teslamate && docker compose start

# 彻底删除整个栈(保留数据卷)
cd /opt/teslamate && docker compose down

# 连数据卷一起删除(危险:数据全丢,删前先 pg_dump 备份)
cd /opt/teslamate && docker compose down -v

# 升级 TeslaMate 版本(改 compose 中 image 标签后执行;新版本启动时自动跑数据库迁移)
cd /opt/teslamate && docker compose pull && docker compose up -d

💡 说明:升级的完整顺序(先备份数据库、逐版本升级、迁移观察)属运维范畴,官方维护文档「Upgrading to a new version」建议的流程是 docker compose pull → docker compose up -d,迁移在应用启动时自动执行,已在 4.5 节实测其机制(Migrations already up 幂等跳过的实测见 D1 篇)。

十一、常见问题(含排障实录)

11.1 主服务容器 Created 未启动(compose up 中断遗留)

现象:docker compose ps 显示 teslamate 服务状态为 Created 而非 Up,其余三个服务正常;Web 端口无监听。

定位:

docker inspect teslamate-4.4.0-app --format '{{.State.Status}} started={{.State.StartedAt}}'
created started=0001-01-01T00:00:00Z

StartedAt 为零值,说明容器只完成了创建、从未收到启动指令——典型于 docker compose up 过程被中断(创建与启动之间断开),或 docker compose create 后未跟 up。容器名若带 <随机串>_ 前缀(如 2d3660166fa2_teslamate-4.4.0-app),是 compose 重建时规避旧容器重名的临时名,同样可用下述命令修复。

解决:在 compose 目录重新 up -d(幂等,只拉起未启动的服务):

cd /opt/teslamate && docker compose up -d
 Container teslamate-4.4.0-db Running 
 Container teslamate-4.4.0-grafana Running 
 Container teslamate-4.4.0-mosquitto Running 
 Container teslamate-4.4.0-app Starting 
 Container teslamate-4.4.0-app Started 

若要顺带恢复规范容器名(去掉临时前缀),强制重建该服务:

cd /opt/teslamate && docker compose up -d --force-recreate teslamate
 Container teslamate-4.4.0-app Recreate 
 Container teslamate-4.4.0-app Recreated 
 Container teslamate-4.4.0-app Starting 
 Container teslamate-4.4.0-app Started 

重建后容器名恢复为 teslamate-4.4.0-app(本机实测,compose 按声明的 container_name 重建)。

11.2 数据库密码不一致:FATAL 28P01 死循环

现象:teslamate 服务反复重启,日志刷屏连接失败。本机实测注入错误密码(DATABASE_PASS 与 POSTGRES_PASSWORD 不一致)的完整日志:

docker logs teslamate-4.4.0-app 2>&1 | tail -3
2026-11-01 11:16:15.111 [error] Postgrex.Protocol (#PID<0.157.0> ("db_conn_2")) failed to connect: ** (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
2026-11-01 11:16:15.112 [error] Postgrex.Protocol (#PID<0.156.0> ("db_conn_1")) failed to connect: ** (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"
2026-11-01 11:16:16.114 [error] Postgrex.Protocol (#PID<0.157.0> ("db_conn_2")) failed to connect: ** (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "teslamate"

解决:把 compose 中 teslamate 与 grafana 服务的 DATABASE_PASS、database 服务的 POSTGRES_PASSWORD 改回同值,然后:

cd /opt/teslamate && docker compose up -d --force-recreate teslamate grafana

实测恢复后日志即转正常(PostgreSQL compatible → Endpoint running → MQTT established,见 4.5 节回显)。注意:若 database 服务的 POSTGRES_PASSWORD 在已有数据后被修改,改环境变量不会改库内密码(该变量只在首次初始化生效),需进库 ALTER USER teslamate WITH PASSWORD '新密码'; 同步。

11.3 Grafana API 用 Basic Auth 返回 401

现象:curl -u admin:q1w2e3r4 http://127.0.0.1:8135/api/search 返回 401(实测回显):

{"extra":null,"message":"Unauthorized","messageId":"auth.unauthorized","statusCode":401,"traceID":""}

定位:Grafana 13 的该定制镜像关闭了 HTTP Basic 认证,Web 登录走表单会话。直接浏览器登录不受影响;脚本化访问需先调表单登录接口拿会话 Cookie。

解决(实测,见 4.7 节):POST /login JSON 体 → 保存 Cookie → 带 Cookie 调 API:

curl -s -c /tmp/gf-cookie.txt -H 'Content-Type: application/json' \
  -d '{"user":"admin","password":"q1w2e3r4"}' http://127.0.0.1:8135/login
curl -s -b /tmp/gf-cookie.txt 'http://127.0.0.1:8135/api/search'

11.4 启动初期 connection refused(非故障)

首次启动偶见两行错误后自愈:

2026-11-01 10:39:39.798 [error] Postgrex.Protocol (#PID<0.156.0> ("db_conn_1")) failed to connect: ** (DBConnection.ConnectionError) tcp connect (database:5432): connection refused - :econnrefused
2026-11-01 10:39:39.798 [error] Postgrex.Protocol (#PID<0.157.0> ("db_conn_2")) failed to connect: ** (DBConnection.ConnectionError) tcp connect (database:5432): connection refused - :econnrefused

原因:四个服务同时拉起,database 完成初始化前 TeslaMate 已发起首连。Ecto 连接池自动重试,几秒内恢复正常(随后日志出现迁移与 Running TeslaMateWeb.Endpoint)。持续刷 econnrefused 超过 1 分钟才按 11.2 排查密码。

11.5 端口被占用

docker compose up -d 报 Bind for 0.0.0.0:8128 failed: port is already allocated 时,先查占用方再改映射:

ss -ltnp | grep -E ':8128|:8135'

改 compose 中 ports: 左侧宿主端口(如 8228:4000)后 docker compose up -d 重建即可,容器内端口 4000/3000 不动。

十二、参考链接