Interface contracts unblocking the parallel fan-out (T01-T07): - 001 config schema (single stack, passphrase + VERSIONS + Pulumi config) - 002 Vault path layout (foundation/<service>/<type>-credentials, camelCase) - 003 container network/DNS/ports/volumes (foundation-net, named volumes) - 004 backup artifact format + restore order (Vault->PG->RustFS->Forgejo) ADR_F001 (layered platform) already satisfied by ADR-004. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4 KiB
Contract — CONTRACT_003 — Container Network, DNS, Ports & Volumes
Between: all bootstrap/components/* that create containers ↔ each other (service discovery)
Status: Agreed (pending implementation validation)
Realizes: PLAN-002 §0 (Layer-0 = containers), §3 · Uses: packages/pulumi-docker (DockerDeployments)
Interface
3.1 Network
- Name:
foundation-net(Docker user-defined bridge — enables name-based DNS). - Subnet:
172.30.0.0/24(configurable, CONTRACT_001network.subnet). - DNS: containers reach each other by container name on
foundation-net. No hardcoded IPs.
3.2 Containers, ports, exposure
| Container name | Image (digest in VERSIONS) | Internal port(s) | Published to host? | Reached by |
|---|---|---|---|---|
foundation-caddy |
caddy | 80, 443 | Yes 80/443 | the internet |
foundation-forgejo |
forgejo | 3000 (http), 22 (sshd) | SSH yes as :2222; HTTP no (via Caddy) |
Caddy → 3000; git over :2222 |
foundation-postgres |
postgres | 5432 | No (internal only) | forgejo |
foundation-rustfs |
rustfs | 9000 (S3 API), 9001 (console) | optional (S3 via Caddy) | forgejo, backup |
foundation-vault |
vault | 8200 | No (via Caddy, restricted) | pulumi, components |
foundation-runner |
act_runner | — (egress only) | No | registers to forgejo |
foundation-registry-cache |
registry:2 | 5000 | No (internal only) | runner (Docker Hub pull-through) |
Exposure rule: only Caddy publishes 80/443; Forgejo SSH is the one extra published port (:2222).
Everything else is internal to foundation-net (PLAN-002 §9.4). The runner SHOULD run on a
separate privileged VM/network (PLAN-001 §4a) — if co-located, fence it (NetworkPolicy-equivalent).
3.3 Internal endpoints (what components write into config/app.ini)
postgres: foundation-postgres:5432
rustfs (S3): http://foundation-rustfs:9000
vault: http://foundation-vault:8200
forgejo (http): foundation-forgejo:3000
registry cache: http://foundation-registry-cache:5000
3.4 Named volumes (the stateful core — back these up, CONTRACT_004)
| Volume | Mounted by | Holds | Backup? |
|---|---|---|---|
foundation-forgejo-data |
forgejo | git repos (POSIX FS — irreducible), app.ini, host SSH keys | Yes — critical |
foundation-postgres-data |
postgres | relational data (users, orgs, CI, package metadata) | Yes (via pg_dump) |
foundation-vault-data |
vault | raft storage | Yes (via raft snapshot) |
foundation-rustfs-data |
rustfs | blobs: LFS, packages, Actions artifacts | Yes (bucket-level) |
foundation-caddy-data |
caddy | ACME certs/account | recreatable (re-issue) — optional |
foundation-caddy-config |
caddy | autosave config | recreatable |
Volume root maps under CONTRACT_001 dataRoot (e.g. /srv/foundation/<volume>).
Ownership
packages/pulumi-dockerprovides theDockerDeploymentsprimitive (name, image, ports, volumes, networks, envs) — vendored from olsicloud4modules/docker.- Each service component owns exactly one container definition + its volumes; the network is owned
by
network.tsand created first.
Assumptions
- Single VM, single Docker daemon, RWO local volumes (no RWX — that's HA/Layer-1, PLAN-001 HA note).
- Container restart policy
unless-stopped; Vault re-seals on restart → unseal helper (ADR-004).
Validation
- After each component:
docker psshows the container healthy; an internalcurl/pg_isreadyfrom a peer container resolves the name and connects. - Only ports 443/80/2222 are reachable from off-host (assert with an external probe).
Change Process
New service = add a row to §3.2 + §3.3, declare its volumes in §3.4, and (if external) justify the published port. Renaming a container is breaking (it is the DNS name) — version this contract.