Initial pilot stack: redis + tcp-ingestion. Designed to grow as the platform's other services land (processor, postgres+timescale, directus, react-spa). - compose.yaml: services as image: references with env-var-driven tags and ports. Redis is internal-only (no host port). TCP port 5027 exposed for GPS device traffic. Persisted Redis volume. - .env.example: documents TCP_INGESTION_TAG, INSTANCE_ID, PORT, LOG_LEVEL. Compose has defaults so the stack starts with no env config. - README: Portainer Repository Stack instructions, manual deploy fallback, network model, planned-services list, why-separate-repo rationale. - .gitignore: ignore .env
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)
- Stack → Add stack → Repository in Portainer.
- Repository URL:
https://git.dev.microservices.al/trm/deploy - Branch:
main - Compose path:
compose.yaml - Environment variables: leave empty for defaults, or set per
.env.example. - (Optional) Enable Automatic updates with a webhook. Portainer will poll or accept a webhook to redeploy when this repo's
mainchanges.
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.