The first CI build failed: the job container (node:22-bookworm) installed
Debian's `docker.io` (Docker 20.10.24, API 1.41), which the host daemon
(29.x, minimum API 1.44) rejects with "client version 1.41 is too old".
Install docker-ce-cli from Docker's official apt repo instead, which is
current and talks to the daemon fine. Verified on the runner: a
node:22-bookworm container with the mounted socket + docker-ce-cli
connects to the 29.1.3 daemon (API 1.52) successfully. This also confirms
the runner's docker_host=automount is working (the client reached the
daemon; only the version was the problem).
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
The Forgejo container registry now lives on a dedicated unproxied
(DNS-only) host, registry.snsnetlabs.com, so large image layers bypass
Cloudflare's ~100 MB request-body cap (the backend image's 262 MB and
317 MB layers previously hit 413 Payload Too Large through the proxied
forgejo.snsnetlabs.com host). The web UI / packages list stays on
forgejo.snsnetlabs.com behind Cloudflare Access SSO.
- build.yml: REGISTRY -> registry.snsnetlabs.com
- deploy/docker-compose.yml: image refs -> registry.snsnetlabs.com
- deploy/README.md: push/pull/login host -> registry.snsnetlabs.com
(packages web UI URL kept on forgejo.snsnetlabs.com)
Also record the versioning convention in HANDOFF + steering: development
happens on even major versions, releases on odd; currently developing v2
(prior released line is v1, see the v1.0 git tag). package.json and the
About panel are not yet bumped to v2.
Validated end to end: built both images on the runner host, pushed to
registry.snsnetlabs.com (backend included, no 413), pulled on racknerd2,
brought the stack up, /api/health returns {"ok":true} over the mesh IP.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
Build the frontend and backend images in CI, push them to the Forgejo
container registry, and deploy to racknerd2 (validation host) over the
NetBird mesh. racknerd2 only pulls + runs (1.9 GiB RAM, never builds).
- .forgejo/workflows/build.yml: on push to main / manual, build both
images and push :latest + :<sha> to forgejo.snsnetlabs.com/sam/...
(installs the docker CLI in the job; relies on the runner's
docker_host=automount to reach the host engine).
- .forgejo/workflows/deploy.yml: manual dispatch; SSH to racknerd2,
docker compose pull + up -d, then /api/health check.
- deploy/docker-compose.yml: registry-image compose. Ports bound to the
mesh IP only (Docker bypasses ufw), so the app is reachable over the
mesh, not the public interface.
- deploy/.env.example + deploy/README.md: deploy host config + full
pipeline/prereq docs.
- .gitignore: ignore real .env / deploy/.env.
Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>