Adds the deployment mechanism for the portfolio site. The site itself is not
deployed yet: Phase 2 has not produced a binary.
- deploy/deploy.sh: build + test (fail fast) -> releases/<ts> -> atomic
`current` symlink flip -> docker compose up -d -> /healthz gate ->
flip back to `previous` and exit non-zero on failure. `--rollback`
restores the previous release in one command. Auto-detects the Go
toolchain in /nix/store when `go` is not on PATH.
- deploy/docker-compose.yml: 127.0.0.1:8096, mem_limit == memswap_limit ==
120m, capped json-file logs (10m x 3), restart unless-stopped.
- deploy/Dockerfile: runtime image only (alpine + prebuilt payload), so a
release needs no toolchain, no network and no package install.
- deploy/rehearse.sh: repeatable proof (21 assertions, exit 0) of deploy,
build fail-fast, health-gate rollback, --rollback and N3 restart.
- deploy/README.md + docs/phase-3-evidence.md: how it works, the build
contract Phase 2 must satisfy, the Caddy block for Sam, and the open
bind-address question (loopback-only vs reachable from .35).
Satisfies DoD items 1, 3 (container), 4, 8. Items 2, 5, 6, 7 need the Phase 2
binary and Sam's Caddy change; recorded as deferred with owners, not claimed.
Co-Authored-By: Paperclip <noreply@paperclip.ing>