# Forgejo on the Swarm cluster Runs as `deploy/forgejo/docker-stack.yml` — the only workload this Swarm cluster carries (the Thermograph app itself stays on the Terraform-managed `docker compose` deploys; see `terraform/README.md`). Pinned to the **beta** node (old VPS) via the `role=forge` label from `deploy/swarm/label-forge-node.sh`. ## Prerequisites 1. Both boxes have joined the swarm (`deploy/swarm/`) and beta is labeled `role=forge`. 2. `docker node ls` (from the manager) shows both `Ready`. ## One-time setup: Swarm secrets Two secrets the stack expects to already exist (Swarm secrets, not files — `external: true` in the stack file, so `docker stack deploy` never creates or sees the values, only references them): ```bash # A strong random password for Forgejo's own Postgres (NOT related to # Thermograph's app database — entirely separate instance/network). openssl rand -base64 32 | docker secret create forgejo_db_password - # The runner registration token. Forgejo can't issue one before it's running, # so this is a two-step dance the first time: docker stack deploy -c deploy/forgejo/docker-stack.yml forgejo # 1. bring Forgejo up (runner will crashloop briefly — expected) # 2. once Forgejo answers at the domain, log in, go to # Site Administration -> Actions -> Runners -> Create new Runner # (or, for a repo-scoped runner: -> Settings -> Actions -> Runners), # copy the token, then: echo -n "PASTE_TOKEN_HERE" | docker secret create forgejo_runner_token - docker service update --force forgejo_runner # picks up the new secret and registers ``` ## Deploy / update ```bash docker stack deploy -c deploy/forgejo/docker-stack.yml forgejo ``` Re-running is safe — Swarm only touches services whose spec actually changed. ## DNS Point the Forgejo domain (default `git.thermograph.org`; override with `FORGEJO_DOMAIN=...` before `docker stack deploy`, Swarm reads it from the deploying shell's environment) at **either** node's public IP — the routing mesh forwards published ports to wherever the task actually landed. ## Why Postgres here and not the Thermograph app's TimescaleDB Separate instance, separate network (`forgejo_net`, not the app's compose network), separate volume. Forgejo is a distinct product with its own schema and its own backup/restore lifecycle — sharing a database with the app would couple two things that should be able to fail, migrate, and restore independently. ## Verifying ```bash docker service ls # all forgejo_* services Running, 1/1 curl -I https://git.thermograph.org/ # 200, valid cert docker service logs forgejo_runner --tail 50 # "runner: successfully registered" then idle ``` ## Rollback / removal ```bash docker stack rm forgejo # volumes (forgejo_data, forgejo_db, ...) survive a stack rm — remove them # explicitly only if you actually want to destroy the Forgejo instance's data. ```