julian 2c49328e12 Add postgres (TimescaleDB-HA + PostGIS) and processor services
postgres service uses timescale/timescaledb-ha:pg16.6-ts2.17.2-all,
which bundles TimescaleDB and PostGIS (and others) ready for CREATE
EXTENSION. This avoids a future DB image swap when Phase 2 of processor
needs PostGIS for the geofence engine. Pinned to a specific tag for
reproducibility; the Docker Hub URL for verification is in the comment.

Data directory mount path is /home/postgres/pgdata/data (the ha-image
layout, different from the stock postgres image's /var/lib/...).
Internal-only — no host port mapping. POSTGRES_USER/PASSWORD/DB env
vars retained as the credential mechanism; if the ha-image rejects
them, fix the env-var scheme without changing the rest of the layout.

processor service references git.dev.microservices.al/trm/processor:
${PROCESSOR_TAG:-main}, depends on Redis + Postgres healthy, takes its
POSTGRES_URL from the same credential vars Postgres bootstraps with.

.env.example documents the new POSTGRES_*, PROCESSOR_TAG, and
PROCESSOR_INSTANCE_ID variables. Important: POSTGRES_PASSWORD only
applies on first boot; rotate via ALTER USER inside psql afterwards.
2026-05-01 10:38:52 +02:00

TRM Deploy

Deployment configuration for the TRM platform. This repo holds the multi-service compose.yaml and per-environment overrides; service code lives in sibling repos under git.dev.microservices.al/trm/.

Layout

deploy/
├── compose.yaml         ← Portainer's Compose path
├── .env.example         ← documented variables; copy to .env locally
├── .gitignore
└── README.md

Services in the stack

Currently:

  • redis — telemetry queue + future Phase 2 connection registry. Internal-only, persisted via named volume.
  • tcp-ingestion — Teltonika telemetry TCP server. Image built by trm/tcp-ingestion's Gitea workflow.

Planned (will be added as they land):

  • processor — consumes telemetry from Redis, writes to PostgreSQL/Timescale.
  • postgres — with TimescaleDB extension.
  • directus — business-plane API and admin UI.
  • react-spa — front-end SPA (static bundle, served via reverse proxy).

See ../docs/wiki/ for the full architecture.

Deploy via Portainer (Repository Stack)

  1. Stack → Add stack → Repository in Portainer.
  2. Repository URL: https://git.dev.microservices.al/trm/deploy
  3. Branch: main
  4. Compose path: compose.yaml
  5. Environment variables: leave empty for defaults, or set per .env.example.
  6. (Optional) Enable Automatic updates with a webhook. Portainer will poll or accept a webhook to redeploy when this repo's main changes.

Before the first deploy, the Portainer host must be authenticated to the Gitea registry:

docker login git.dev.microservices.al

(Or configure registry credentials in Portainer's Registries UI — preferred.)

Deploy without Portainer (manual)

git clone https://git.dev.microservices.al/trm/deploy
cd deploy
cp .env.example .env
# edit .env if you want to override defaults
docker compose pull
docker compose up -d

Updating

When a service publishes a new image (Gitea workflow on push to main):

docker compose pull
docker compose up -d

Portainer with automatic updates does this automatically.

To pin a specific build for production, set the relevant *_TAG variable in .env (or in Portainer's stack environment) to a commit SHA — e.g. TCP_INGESTION_TAG=af06973.

Network model

  • One internal Compose network (trm_default).
  • Redis is not bound to a host port — only reachable from other services in the stack via service-name DNS (redis://redis:6379).
  • tcp-ingestion's TCP port (5027 by default) is bound to the host so devices can reach it.
  • Other Redis instances on the same host can keep using port 6379 freely; this stack does not collide with them.

Environment variables

See .env.example for the documented set with defaults and explanations.

Why a separate repo

Compose covers multiple services; placing it inside any one service repo creates ownership ambiguity (which service "owns" the Postgres definition? the Redis volume?). Keeping deploy config in its own repo means:

  • Compose changes are versioned independently of any service's code.
  • Portainer's Repository stack tracks one source of truth.
  • Per-environment overrides (e.g. compose.stage.yaml, compose.prod.yaml) can be added cleanly later.
  • Adding a new service is a one-file change here, not a coordinated edit across repos.
S
Description
No description provided
Readme 60 KiB