thermograph/backend/docker-compose.test.yml
Emi Griffith d60e6c0abe
All checks were successful
PR build (required check) / changes (pull_request) Successful in 10s
secrets-guard / encrypted (pull_request) Successful in 9s
shell-lint / shellcheck (pull_request) Successful in 10s
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Successful in 1m11s
PR build (required check) / build-backend (pull_request) Successful in 1m41s
PR build (required check) / gate (pull_request) Successful in 3s
web/worker: add a process-level liveness heartbeat
ProdWebContainerSilent and ProdWorkerContainerSilent alert on Docker
container-stdout volume, which isn't a valid liveness signal for either
role: web's real access logging lives in the file-tailed app-json
source, not stdout, and worker's stdout is unconditionally dropped by
Alloy's own relabel rule. Both fired for hours against a healthy prod.

Give web and worker a real audit.log_heartbeat() beat, same pattern the
subscription notifier already uses, tagged daemon=ROLE and unguarded
across every uvicorn worker/replica (a beat is a single local file
append, nothing like the notifier's leader-election cost). Observability
alert rules to consume this land separately.
2026-07-24 20:52:41 -07:00

41 lines
1.9 KiB
YAML

# Boot-smoke harness: run the backend's OWN image against a throwaway TimescaleDB and
# assert it actually boots + serves its contract (build alone doesn't prove boot). Used
# by scripts/smoke.sh; not a deploy file. DB data is tmpfs (ephemeral) — no volume, no
# residue. See Makefile `smoke` and README.
services:
db:
image: timescale/timescaledb:${TIMESCALEDB_TAG:-latest-pg18}
environment:
POSTGRES_USER: thermograph
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-smoke}
POSTGRES_DB: thermograph
tmpfs:
# pg18 images place PGDATA in a major-version subdir under the mount, so mount at
# /var/lib/postgresql (matches the infra compose), not /var/lib/postgresql/data.
- /var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U thermograph -d thermograph"]
interval: 3s
timeout: 5s
retries: 20
backend:
# Defaults to a locally-built `:local` image (scripts/smoke.sh builds it). In CI,
# set BACKEND_IMAGE_TAG=sha-<12hex> to smoke the exact published image.
image: ${REGISTRY_HOST:-git.thermograph.org}/${BACKEND_IMAGE_PATH:-emi/thermograph-backend/app}:${BACKEND_IMAGE_TAG:-local}
depends_on:
db:
condition: service_healthy
environment:
THERMOGRAPH_DATABASE_URL: postgresql+asyncpg://thermograph:${POSTGRES_PASSWORD:-smoke}@db:5432/thermograph
# Required at import (web/app.py). The smoke never exercises a proxied page, so an
# unreachable placeholder is fine — it only hits /healthz and {BASE}/api/version.
THERMOGRAPH_FRONTEND_BASE_INTERNAL: http://127.0.0.1:1
THERMOGRAPH_BASE: "/"
THERMOGRAPH_ENABLE_NOTIFIER: "0"
THERMOGRAPH_ENABLE_HEARTBEAT: "0"
PORT: "8137"
WORKERS: "1"
ports:
# Host port defaults to 18137 to avoid colliding with a running dev server on 8137.
- "127.0.0.1:${SMOKE_HOST_PORT:-18137}:8137"