diff --git a/.env.example b/.env.example index 61b1db9..e82ac0f 100644 --- a/.env.example +++ b/.env.example @@ -23,6 +23,34 @@ TCP_INGESTION_INSTANCE_ID=stage-1 # give each a distinct host port (e.g. 5028, 5029). TCP_INGESTION_PORT=5027 +# --------------------------------------------------------------------- +# postgres / TimescaleDB +# --------------------------------------------------------------------- + +# Database superuser, password, and default database. Created on first +# boot of the postgres container; the volume persists them after that. +# IMPORTANT: change POSTGRES_PASSWORD before deploying to production. +# Changing it after first boot has no effect — the volume already has +# the password baked in. To rotate, ALTER USER inside psql. +POSTGRES_USER=trm +POSTGRES_PASSWORD=trm-pilot-change-me +POSTGRES_DB=trm + +# --------------------------------------------------------------------- +# processor +# --------------------------------------------------------------------- + +# Image tag to pull. `main` auto-tracks the latest commit on the main branch. +# In production, pin to a specific commit SHA for reproducibility. +# Example: PROCESSOR_TAG=9791620 +PROCESSOR_TAG=main + +# Instance identifier — must be stable across the lifetime of the process, +# AND unique per running instance (it's used as the Redis consumer-group +# member name; two instances with the same name will read from the same +# Pending Entries List, which is undefined behaviour). +PROCESSOR_INSTANCE_ID=processor-1 + # --------------------------------------------------------------------- # Shared # --------------------------------------------------------------------- diff --git a/compose.yaml b/compose.yaml index 88b363a..b7bfccd 100644 --- a/compose.yaml +++ b/compose.yaml @@ -56,10 +56,58 @@ services: LOG_LEVEL: ${LOG_LEVEL:-info} restart: unless-stopped + # ------------------------------------------------------------------- + # postgres — PostgreSQL 16 with TimescaleDB + PostGIS extensions + # (and others) bundled. Image: timescale/timescaledb-ha, `-all` suffix + # = all extensions present and ready for `CREATE EXTENSION`. + # + # Schema is owned by Directus (when it lands); the `positions` + # hypertable is owned by the processor's migration runner. + # Internal-only; no host port mapping. + # + # The image tag should be reviewed every 3–6 months. Pick the latest + # stable `pg16-ts*-all` build from Docker Hub: + # https://hub.docker.com/r/timescale/timescaledb-ha/tags + # Pin to a specific tag (not rolling `pg16`) so deploys are reproducible. + # ------------------------------------------------------------------- + postgres: + image: timescale/timescaledb-ha:pg16.6-ts2.17.2-all + expose: + - '5432' + volumes: + - postgres-data:/home/postgres/pgdata/data + environment: + POSTGRES_USER: ${POSTGRES_USER:-trm} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-trm-pilot-change-me} + POSTGRES_DB: ${POSTGRES_DB:-trm} + restart: unless-stopped + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-trm} -d ${POSTGRES_DB:-trm}'] + interval: 10s + timeout: 3s + retries: 5 + + # ------------------------------------------------------------------- + # processor — consumes telemetry from Redis, writes to Postgres. + # Built by git.dev.microservices.al/trm/processor's Gitea workflow. + # ------------------------------------------------------------------- + processor: + image: git.dev.microservices.al/trm/processor:${PROCESSOR_TAG:-main} + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + environment: + NODE_ENV: production + INSTANCE_ID: ${PROCESSOR_INSTANCE_ID:-processor-1} + REDIS_URL: redis://redis:6379 + POSTGRES_URL: postgres://${POSTGRES_USER:-trm}:${POSTGRES_PASSWORD:-trm-pilot-change-me}@postgres:5432/${POSTGRES_DB:-trm} + LOG_LEVEL: ${LOG_LEVEL:-info} + restart: unless-stopped + # ------------------------------------------------------------------- # Future services land here: - # - processor: consumes telemetry from Redis, writes to DB - # - postgres: PostgreSQL with TimescaleDB extension # - directus: business-plane API + admin UI # - react-spa: front-end (static, served via nginx or Caddy) # See ../docs/wiki/ for the platform architecture. @@ -67,3 +115,4 @@ services: volumes: redis-data: + postgres-data: