thermograph/infra
emi d42a57a011
All checks were successful
secrets-guard / encrypted (push) Successful in 5s
shell-lint / shellcheck (push) Successful in 6s
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 6s
PR build (required check) / build-backend (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Has been skipped
shell-lint / shellcheck (pull_request) Successful in 9s
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 2s
ci: collapse the eight deploy and build-push workflows into two (#87)
2026-07-25 07:48:49 +00:00
..
.claude/skills/key-gaps key-gaps: the key regex was blind to digits, inventing missing secrets 2026-07-24 15:57:15 -07:00
deploy ci: collapse the eight deploy and build-push workflows into two (#87) 2026-07-25 07:48:49 +00:00
lake-iceberg Iceberg conversion container for the ERA5 lake (infra/lake-iceberg) (#24) 2026-07-23 22:56:27 +00:00
ops ops/iceberg.sh: read-only Iceberg lake queries across all environments (#23) 2026-07-24 19:34:30 +00:00
terraform Log hygiene: Alloy CPU, Loki chunks/limits, Caddy field-stripping (#36) 2026-07-24 04:37:41 +00:00
.env.example daemon: move the Discord gateway and scheduler out of the web process into Go (#21) 2026-07-23 22:49:54 +00:00
.gitignore infra: mirror LAN dev secrets under $HOME for snap-confined Docker (#85) 2026-07-25 07:16:08 +00:00
.sops.yaml Subtree-merge thermograph-infra (origin/main) into infra/ 2026-07-22 22:01:11 -07:00
ACCESS.md Subtree-merge thermograph-infra (origin/main) into infra/ 2026-07-22 22:01:11 -07:00
CLAUDE.md docs: rewrite the agent context layer to match the live system (#81) 2026-07-25 07:08:54 +00:00
DEPLOY-DEV.md secrets: vault dev and Centralis; render dev without common.yaml 2026-07-24 18:10:51 -07:00
DEPLOY.md observability: add the estate's first alerting; supervise Postfix 2026-07-24 13:19:19 -07:00
docker-compose.dev.yml infra: mirror LAN dev secrets under $HOME for snap-confined Docker (#85) 2026-07-25 07:16:08 +00:00
docker-compose.openmeteo.yml Subtree-merge thermograph-infra (origin/main) into infra/ 2026-07-22 22:01:11 -07:00
docker-compose.yml ci: collapse the eight deploy and build-push workflows into two (#87) 2026-07-25 07:48:49 +00:00
Makefile Subtree-merge thermograph-infra (origin/main) into infra/ 2026-07-22 22:01:11 -07:00
README.md docs: rewrite the agent context layer to match the live system (#81) 2026-07-25 07:08:54 +00:00

infra/

Infrastructure for Thermograph: Terraform host provisioning, the SOPS+age secrets vault, WireGuard/Swarm networking, Forgejo, Caddy, mail, and the deploy scripts that run the already-built app images on each host. This is a domain of the emi/thermograph monorepo — hosts' /opt/thermograph is a checkout of the whole monorepo, and infra/ never builds app source; it only runs published images.

  • terraform/ — provisions/configures hosts (SSH-driven by default; an optional GCP-creating module is scaffolded, no live resources yet). See terraform/README.md. No tfstate is persisted anywhere — treat apply as executable documentation, not a routine operation.
  • deploy/secrets/ — the git-native SOPS+age secrets vault (every app secret, encrypted at rest, rendered at deploy time). See deploy/secrets/README.md.
  • deploy/swarm/, deploy/forgejo/ — the WireGuard/Swarm cluster hosting Forgejo (git + CI + registry). See ACCESS.md.
  • deploy/deploy.sh — the single deploy entry point for beta and prod. Takes SERVICE=backend|frontend|all plus BACKEND_IMAGE_TAG/FRONTEND_IMAGE_TAG, resets the host checkout, renders secrets, and routes to the right orchestrator.
  • deploy/stack/ — the Swarm path, live on prod: thermograph-stack.yml (db, web, worker, lake, daemon, frontend, autoscaler, autoscaler-lake), deploy-stack.sh, autoscale.sh, and the LB. Rolling updates are start-first, health-gated, with auto-rollback. STACK_TEST=1 rehearses the whole stack on throwaway volumes and ports.
  • docker-compose*.yml — the compose path, live on beta and LAN dev (db, backend, lake, daemon, frontend). docker-compose.dev.yml is the LAN overlay; docker-compose.openmeteo.yml is the self-hosted Open-Meteo overlay.

Which path a host takes is decided by /etc/thermograph/deploy-mode: the string stack makes deploy.sh exec deploy/stack/deploy-stack.sh; anything else is compose. The workflows never need to know which mode a host runs.

Branches & how changes reach each environment

  • main — what prod and beta run. infra-sync.yml fires on a push to main touching infra/**, fast-forwards each host's /opt/thermograph checkout and re-renders /etc/thermograph.env from the vault. It deliberately does not roll any service: image tags are the app domains' axis, not infra's. A compose or stack change that must recreate containers takes effect on the next app deploy, or a by-hand SERVICE=all … deploy/deploy.sh.
  • dev — what LAN dev would run via deploy/deploy-dev.sh. The CI trigger for this is currently inert (the LAN box still holds a split-era checkout); use make dev-up locally.
  • release — consumed by app deploys only. Both hosts track infra via main; prod's app images are staged by release, but its checkout follows main.

Note the asymmetry with the app domains: app code IS environment-staged (devmainrelease maps to LAN→beta→prod via image tags); infra is not.