feat(infra): distribution proxy in prod compose + dev-sso Traefik registry (BUNYIP-32) #33

Merged
nrupard merged 2 commits from feat/bunyip-32-distribution-infra into main 2026-06-02 16:30:19 +02:00
Owner

What

Infrastructure wiring for the distribution proxy (BUNYIP-32, subtask of the BUNYIP-28 story): production compose env + volumes, dev-sso Traefik routing for the OCI registry subdomain, and the runbook section that documents it.

Changes

  • compose.yml (production): full distribution env (FORGEJO_* secret refs, download cache config, OCI registry config with inline operator docs covering the TLS reverse-proxy requirements), OCI listener published on loopback for the proxy, and NAMED cache volumes (bunyip-oci-cache, bunyip-download-cache) per the governance naming convention and the BUNYIP-31 bind-mount finding.
  • compose.dev-sso.yml: the api joins network-traefik-public and gets router labels for <user>-bunyip-registry.a8n.run -> port 18081. OCI_REGISTRY_SERVICE is pinned to that hostname and the localhost realm from compose.dev.yml is cleared, so the token realm derives to https://<service>/auth/token behind Traefik's real certificate.
  • Entrypoint discovery: the registry router binds BOTH web-secure and nebula-secure. The two dev boxes map :443 to different Traefik entrypoints (dev-01 -> web-secure, desktop-02 -> nebula-secure); binding only one 404s on the other box. This is the same split behind the runbook's pre-existing open item about bunyip-web's entrypoint.
  • dev-sso runbook section 9: required .env, wiring explanation, smoke test, Mac access.

Verification (live on dev-01)

  • All three compose combinations render: prod, dev, dev + sso overlay.
  • The api recreated with the overlay serves the registry through Traefik with a valid Let's Encrypt certificate.
  • docker login + docker pull psa-systems-private/bunyip-api:v0.1.1 succeed end to end over https://nate-bunyip-registry.a8n.run.
  • Plain just dev mode restored and re-verified afterwards (localhost service value back in place).

Remaining BUNYIP-32 acceptance criteria

  • "just dev boots with both verticals enabled/disabled" - done in BUNYIP-31 (PR #27).
  • "just dev-sso exposes the registry and docker login works" - verified here (api-only overlay; full just dev-sso also needs the mokosh OIDC client vars, unrelated to the registry).
  • "Production compose documents every new env var" - done.
  • "All new volumes/services follow the naming convention" - done.
## What Infrastructure wiring for the distribution proxy (**BUNYIP-32**, subtask of the BUNYIP-28 story): production compose env + volumes, dev-sso Traefik routing for the OCI registry subdomain, and the runbook section that documents it. ## Changes * **compose.yml (production)**: full distribution env (FORGEJO_* secret refs, download cache config, OCI registry config with inline operator docs covering the TLS reverse-proxy requirements), OCI listener published on loopback for the proxy, and NAMED cache volumes (`bunyip-oci-cache`, `bunyip-download-cache`) per the governance naming convention and the BUNYIP-31 bind-mount finding. * **compose.dev-sso.yml**: the api joins `network-traefik-public` and gets router labels for `<user>-bunyip-registry.a8n.run` -> port 18081. `OCI_REGISTRY_SERVICE` is pinned to that hostname and the localhost realm from compose.dev.yml is cleared, so the token realm derives to `https://<service>/auth/token` behind Traefik's real certificate. * **Entrypoint discovery**: the registry router binds BOTH `web-secure` and `nebula-secure`. The two dev boxes map :443 to different Traefik entrypoints (dev-01 -> web-secure, desktop-02 -> nebula-secure); binding only one 404s on the other box. This is the same split behind the runbook's pre-existing open item about bunyip-web's entrypoint. * **dev-sso runbook section 9**: required .env, wiring explanation, smoke test, Mac access. ## Verification (live on dev-01) * All three compose combinations render: prod, dev, dev + sso overlay. * The api recreated with the overlay serves the registry through Traefik with a valid Let's Encrypt certificate. * `docker login` + `docker pull psa-systems-private/bunyip-api:v0.1.1` succeed end to end over `https://nate-bunyip-registry.a8n.run`. * Plain `just dev` mode restored and re-verified afterwards (localhost service value back in place). ## Remaining BUNYIP-32 acceptance criteria * "just dev boots with both verticals enabled/disabled" - done in BUNYIP-31 (PR #27). * "just dev-sso exposes the registry and docker login works" - verified here (api-only overlay; full `just dev-sso` also needs the mokosh OIDC client vars, unrelated to the registry). * "Production compose documents every new env var" - done. * "All new volumes/services follow the naming convention" - done.
feat(infra): wire the distribution proxy into prod compose + dev-sso Traefik (BUNYIP-32)
Some checks failed
Check / fmt / clippy / build / test (pull_request) Failing after 17s
c11c4a7e44
Production compose.yml gains the full distribution-proxy surface: FORGEJO_BASE_URL / FORGEJO_API_TOKEN (service-account secret, .env only), download cache config, and the OCI registry env (enabled flag, fixed container port 18081, OCI_REGISTRY_SERVICE for the public hostname, cache and rate-limit knobs), each documented inline including the reverse-proxy requirements (TLS hostname routing for /v2/* and /auth/token, no response buffering). The caches are NAMED volumes (bunyip-oci-cache, bunyip-download-cache) per the governance naming convention and the BUNYIP-31 finding that bind mounts break blob writes; the registry listener publishes on loopback for the reverse proxy, mirroring the api port pattern.

compose.dev-sso.yml routes the OCI registry through Traefik on a per-developer hostname (<user>-bunyip-registry.a8n.run): the api joins network-traefik-public with router labels forwarding to port 18081, pins OCI_REGISTRY_SERVICE to that hostname, and clears the localhost realm from compose.dev.yml so the token realm derives to https://<service>/auth/token behind Traefik's TLS. The router binds BOTH secure entrypoints (web-secure + nebula-secure) because the two dev boxes map :443 to different entrypoints; binding only nebula-secure 404s on dev-01 (verified live, and the same split is behind the runbook's existing open item about bunyip-web).

The dev-sso runbook gains section 9: required .env additions, how the wiring works (including the dual-entrypoint discovery), a smoke test, and Mac access notes. Section 4 points at it.

Verification (live on dev-01): all three compose combinations render (prod, dev, dev+sso overlay); the api recreated with the overlay serves the registry through Traefik with a valid certificate; docker login and docker pull of psa-systems-private/bunyip-api:v0.1.1 succeed end to end over https://nate-bunyip-registry.a8n.run; plain `just dev` mode restored and unaffected afterwards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(infra): address code-review findings on the distribution infra PR
Some checks failed
Check / fmt / clippy / build / test (pull_request) Failing after 18s
Create release / Create release from merged PR (pull_request) Has been skipped
a187680e3c
Fixes from a 10-finding review of PR #33:

- OciConfig::validate() now rejects an empty OCI_REGISTRY_SERVICE (and a realm whose URL has no host) with a precise error, so enabling the registry with the compose default ${OCI_REGISTRY_SERVICE:-} fails fast at startup instead of advertising an unusable realm. New unit tests cover the empty and port-only service cases and document the WHATWG slash-normalization subtlety that makes an explicit https:///auth/token realm parse rather than error.
- compose.dev-sso.yml: OCI_REGISTRY_SERVICE gains the ${USER:?} guard the sibling OIDC vars already had, and the bunyip-web router now binds both secure entrypoints like the registry router, fixing the documented section 8 open item (web UI 404 on dev-01) with the root cause this PR established.
- compose.yml: the dual meaning of HOST_IP (container bind env vs host publish interface) is documented at the ports block so operators do not publish the plaintext listeners on every interface by mistake; the duplicated operator prose is trimmed to pointers at the canonical source.
- dev-docs/oci-registry-verification.md is now the canonical home for production configuration rules and gains: a dev-sso/Traefik verification section (it previously only covered localhost), and reference reverse-proxy configs for Caddy, Traefik file-provider, and nginx (including the body-size/buffering directives whose defaults break image pulls).
- .env.example documents every compose ${VAR}: BUNYIP_OCI_PORT beside the other host ports, the distribution tuning knobs (cache caps, daily limits), and the production enable/service pair, plus the HOST_IP publish-interface clarification.
- The dev-sso runbook section 1 table no longer claims the api is internal-only; section 9 is trimmed to dev-sso-specific content pointing at just verify-oci and the verification doc, the smoke test notes the docker-login password prompt, and the misleading "plain just dev still works at the same time" wording is replaced with an accurate one-container-two-paths explanation.
- just dev-sso prints the registry URL alongside the hub URL.
- Production secret handling (FORGEJO_API_TOKEN et al as plain env vars, visible via docker inspect) is out of scope here and tracked as BUNYIP-38.

Verification: workspace check green; config tests pass (the oci_config_enabled_when_set failure is the pre-existing BUNYIP-36 env-var race); zero new clippy violations vs main; config.rs rustfmt-clean; all three compose combinations render; both dev-sso routers bind web-secure,nebula-secure; the USER guard fails compose config when USER is unset; justfile parses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch feat/bunyip-32-distribution-infra 2026-06-02 16:30:19 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
psa-systems/bunyip!33
No description provided.