feat(bootstrap): forgejo forge — postgres + rustfs + ssh (T08)

foundation-forgejo (forgejo:11, digest-pinned) on foundation-net: git repos on the
foundation-forgejo-data volume (the irreducible state), metadata in external
Postgres, blobs in RustFS (default storage + LFS over the minio API). Config is
seeded via FORGEJO__section__KEY env -> app.ini; INSTALL_LOCK skips the web
installer and the crypto secrets (SECRET_KEY/INTERNAL_TOKEN/JWT) auto-generate and
persist in the volume. HTTP 3000 is internal (Caddy fronts forge.olsitec.net); the
image's openssh sshd owns container :22 (START_SSH_SERVER=false — explicitly, so a
stale app.ini value can't keep Forgejo's built-in Go SSH server colliding on :22),
published on host :22 (scp-form goal) and :2222 (CONTRACT_003). A healthz-gated
ready command is GATE B for T09/T10.

Live on cx33 Helsinki: container healthy, https://forge.olsitec.net = 200 over a
valid Let's Encrypt cert, API 11.0.15, sshd reachable on :22 and :2222.
Acceptance T08 met.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andreas Niemann 2026-06-30 22:23:39 +02:00
parent 6a7c28b54c
commit f1e1d6facd
3 changed files with 173 additions and 3 deletions

View file

@ -60,7 +60,7 @@
# caddy:2 lacks it) — recipe + pinned base digests + module version live in
# containers/caddy-cloudflare/Dockerfile. This is the pinned FINAL base it derives.
IMAGE_CADDY=caddy:2.10@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb
IMAGE_FORGEJO=codeberg.org/forgejo/forgejo:11@sha256:PIN_DIGEST
IMAGE_FORGEJO=codeberg.org/forgejo/forgejo:11@sha256:d98d860ea64fd36cb0aabf0b46bbe1a37566b498eee4af0a6b246d5a45759d6d
IMAGE_POSTGRES=postgres:17@sha256:5c855ad7b85e68e48a62f34662853f38b57c1c1d80f3a927ab58034fd6d31c5e
IMAGE_VAULT=hashicorp/vault:1.18@sha256:750bb37c1638fa194ab37053a81618c61bb0491ddec6fccac87c07a8e6cd8166
IMAGE_RUSTFS=rustfs/rustfs:latest@sha256:fa19210ac4697c79d7ccca1ec9b0eb91aebacc6691991ffb14014bb3c67e6cc3