Files
oikos/containers/128-trmnl.md
dtoro fffa5560eb trmnl (128): provisioned — container page, inventory, ingress
LXC 128 trmnl hosts the TRMNL plugins middleware (dtoro/terminalito), polled by
TRMNL cloud. trmnl-plugins.service on :9851; Caddy block + LE cert; VPS traefik
router trmnl-public + cert mirror. Public path pending VPS<->home netbird route
recovery (was "No networks available" at provision time, artifacto/blog 504 too).
LAN Technitium record + SOPS enrollment + Google/MVG creds pending. Plan -> In Progress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 17:24:31 +02:00

3.2 KiB

128 — trmnl

Self-hosted middleware for TRMNL e-ink plugins. TRMNL cloud polls it; it fetches/shapes live data into JSON the plugin's Liquid template renders.

At a glance

  • Hostname: trmnl
  • IP: 192.168.8.211
  • Privilege: unprivileged
  • Resources: 1 core / 768 MiB RAM / 8 GiB rootfs (Debian 13)
  • Mounts: none
  • Public hostname: trmnl.hubris.network (via VPS ingress)

Role

Runs one FastAPI aggregator (server.app:app, port 9851) that mounts a router per plugin from the dtoro/terminalito repo. First consumer: munich-home (/munich-home/dashboard) — weather (Open-Meteo), MVG transit, Google Calendar, plus server-side Kita/quote logic. Talks out to the public internet for those APIs; TRMNL cloud polls it inbound every 15 min. Bearer-token gated (TRMNL_POLL_TOKEN); /health is open.

Service / port map

Service Listen Notes
trmnl-plugins 0.0.0.0:9851 uvicorn aggregator; EnvironmentFile=/etc/trmnl-plugins/env

Storage / config paths

  • /opt/terminalito — git checkout (origin = internal gitea http://192.168.8.121:3000/dtoro/terminalito.git)
  • /opt/terminalito/server/.venv — venv
  • /etc/trmnl-plugins/envTRMNL_POLL_TOKEN (+ Google/MVG creds once enrolled)
  • /etc/systemd/system/trmnl-plugins.service

Auto-deploy

Not yet wired. Manual deploy: pct exec 128 -- /opt/terminalito/server/deploy/deploy.sh. When wired it follows auto-deploy Shape B (/opt/terminalito-deploy/, gitea webhook on dtoro/terminalito, add 192.168.8.211 to gitea ALLOWED_HOST_LIST).

Secrets

Not yet SOPS-enrolled. The poll token is set directly in /etc/trmnl-plugins/env. Google Calendar + MVG creds are pending: enroll via homelab client add trmnl + bootstrap, add secrets/trmnl-oauth.yaml, then server/deploy/render-env.sh builds the env from homelab secret trmnl-oauth. Until then calendar/transit cards degrade to empty; weather works.

Changelog

2026-06-24 — provisioned

LXC 128 created (Debian 13, unprivileged, 192.168.8.211). Deployed trmnl-plugins.service on :9851 from dtoro/terminalito. Caddy block added (dtoro/caddy-conf) + LE cert via IONOS DNS-01; verified /health 200 and /munich-home/dashboard (live weather) through Caddy. Cert mirrored to VPS (trmnl.fullchain.crt/trmnl.privkey.key) + traefik router trmnl-public192.168.8.211:9851 added to /opt/traefik-dynamic.yaml. Public path pending: VPS↔home netbird route was down at provision time (No networks available, 3/6 peers — artifacto/blog also 504); resolves when the mesh route recovers. LAN pending: Technitium A record not yet added. Not SOPS-enrolled; Google/MVG creds pending.