TeslaMate Service Operations¶
Stack Overview¶
- TeslaMate core app published through Podman with pinned image digests for deterministic deploys.
- Optional-but-enabled components on
forge: local PostgreSQL role/database plus shared services (central Grafana + EMQX MQTT broker). - Reverse proxy entries for TeslaMate (
teslamate.${domain}) and the EMQX dashboard (mqtt.${domain}) protected via caddy-security/PocketID authentication. - Restic backups plus ZFS dataset replication (Sanoid) keep
/tank/services/teslamatesynchronized tonas-1. - Prometheus/Loki wiring ensures metrics (
/metricson port 4000) and journald logs are exported automatically.
Bootstrap Checklist¶
- DNS – Publish
teslamate.<domain>(TeslaMate UI) andmqtt.<domain>(EMQX dashboard) to your public zone. - SSO – Configure PocketID groups referenced by the modules (TeslaMate UI:
admins, MQTT dashboard:admins). - Secrets – Add the SOPS entries shown below plus the shared Restic password at
restic/password. - Dataset – Create
tank/services/teslamate(or import from backup) on the target host; permissions land on theteslamatesystem user/group during activation. - Replication Target – Make sure
nas-1.holthome.nettrusts theforgereplication key listed in the host module (or update both sides accordingly). - Tesla API Prep – Generate a long-lived encryption key and ensure you can issue a fresh Tesla API refresh token before first login.
Secret Matrix¶
| Key | Purpose | Owner/Mode | Notes |
|---|---|---|---|
teslamate/database_password |
Postgres role password injected into the container and DB provisioning jobs | root:postgres / 0440 |
Used by local Postgres via modules.services.postgresql.databases. |
teslamate/encryption_key |
ENCRYPTION_KEY consumed by TeslaMate to encrypt Tesla refresh tokens |
root:root / 0400 |
Generate 256-bit random and keep stable across redeploys. |
teslamate/mqtt_password |
Password for the EMQX user teslamate |
root:root / 0400 |
Shared between TeslaMate and other consumers (e.g., Home Assistant automations). |
emqx/dashboard_password |
Admin password for the EMQX web console | root:root / 0400 |
Required whenever the dashboard + reverse proxy are enabled. |
restic/password |
Shared Restic repository password used by the preseed and scheduled backups |
root:root / 0400 |
Existing secret reused from other services. |
Use
sops hosts/forge/secrets.yaml(or the Task helper) to add/update these entries; activation will render them at the paths declared inhosts/forge/secrets.nix.
Deploy / Update Flow¶
- Edit
hosts/forge/services/teslamate.nix(or another host) to adjust registry, domains, and caddy-security policies. - Validate locally:
nix build .#nixosConfigurations.forge.config.system.build.toplevel --dry-run. - Push to Git, then run
task nix:apply-nixos host=forge NIXOS_DOMAIN=holthome.netto apply. - Confirm systemd units are healthy:
systemctl status podman-teslamate.servicesystemctl status podman-emqx.service- Verify ingress via PocketID authentication and ensure Grafana dashboards load via the shared observability stack.
Backups & Restore¶
- Restic backups target
nas-primaryvia the shared backup module; tagsteslamate+telemetrymake filtering easy. preseedis enabled withrepositoryUrl = /mnt/nas-backup, so first boot will try syncoid → local restore → Restic (in that order) before starting containers.- Sanoid replicates
tank/services/teslamatetobackup/forge/zfs-recv/teslamateonnas-1using the provided host key. Adjustmodules.backup.sanoid.datasetsif you move datasets. - To perform a manual Restic restore:
- Stop TeslaMate containers.
- Run
restic -r <repo> restore latest --target /tank/services/teslamate --include teslamate(password fromrestic/password). - Restart services and watch the importer logs.
Monitoring & Alerts¶
- Prometheus automatically scrapes TeslaMate via the shared metrics registry, labeled
service="teslamate". - EMQX exports Prometheus metrics and a container liveness alert (
emqx-service-down) fires if the broker stops accepting connections. - Journald logs are shipped via the
loggingsubmodule; query byunit="podman-teslamate.service"(orpodman-emqx.service) in Loki. - Notifications inherit the global
modules.notificationsdefaults. Failures emit to thesystem-alertschannel unless overridden per-host.
Operational Tips¶
- Importing legacy CSVs: drop files into
${dataDir}/import(default/var/lib/teslamate/import) and restart TeslaMate. - MQTT access for automations: point clients at the shared EMQX host/port (default
localhost:1883internally,mqtt.${domain}if you terminate TLS elsewhere). - Updating container images: bump the
imageattributes in either the module defaults or host override, run the dry-run build, then reapply NixOS. - To temporarily pause data collection, stop only the TeslaMate container; the shared Grafana + EMQX services keep their state persisted under their own datasets.