Phase 3: dual bind per Sam's decision (DoD 3 amended, DoD 1/4/8 re-evidenced)
Sam answered the bind question on AUD-133 (2026-10-26):
"A - dual bind: 127.0.0.1:8096 and 192.168.20.13:8096".
- docker-compose: publish 127.0.0.1 and ${APP_LAN_IP:-192.168.20.13}, never 0.0.0.0
- deploy.sh: carry APP_LAN_IP into the release .env, --lan-ip flag, health gate
now requires /healthz 200 on loopback AND the LAN address
- rehearse.sh: assert both binds, no wildcard, LAN reachability; KEEP_REHEARSAL
now really keeps the container/image; N3 waits up to 20s instead of 3s
- docs/phase-3-evidence.md: decision recorded, new measured output
DoD: 1, 3 (as amended by Sam), 4, 8 met with recorded output. 2, 5, 6 deferred
on the Phase 2 binary; 7 is Sam's Caddy apply. rehearse.sh 24/24, exit 0.
This commit is contained in:
@@ -8,7 +8,7 @@ host: change these files in git and deploy again.
|
||||
|---|---|
|
||||
| `deploy.sh` | build + test → release → flip → `up -d` → health gate → rollback on failure |
|
||||
| `deploy.sh --rollback` | restore the previous release in one command |
|
||||
| `docker-compose.yml` | runtime container: `127.0.0.1:8096`, `mem_limit == memswap_limit == 120m`, capped logs |
|
||||
| `docker-compose.yml` | runtime container: published on `127.0.0.1:8096` **and** `192.168.20.13:8096` (never `0.0.0.0`), `mem_limit == memswap_limit == 120m`, capped logs |
|
||||
| `Dockerfile` | runtime image only — alpine + the prebuilt release payload, no toolchain, no network |
|
||||
| `rehearse.sh` | repeatable proof that deploy, fail-fast, health-gate rollback and `--rollback` all work |
|
||||
|
||||
@@ -67,7 +67,8 @@ the script works on a host where `go` is not on `PATH`.
|
||||
It builds three throwaway services in a scratch directory, runs the real script
|
||||
against the real release root and the real port, and asserts:
|
||||
|
||||
1. a good release deploys, answers `/healthz`, publishes on `127.0.0.1` only,
|
||||
1. a good release deploys, answers `/healthz` over loopback and the LAN
|
||||
address, publishes on exactly those two addresses with no wildcard bind,
|
||||
and has `memswap_limit == mem_limit`;
|
||||
2. a build failure exits non-zero, leaves `current` untouched and keeps serving;
|
||||
3. a release whose `/healthz` is `500` is rolled back by the health gate, exits
|
||||
@@ -85,9 +86,26 @@ host swap on a host that is already swapping. Measured RSS for a Go static
|
||||
server is single-digit MiB; `deploy.sh` prints the real figure after every
|
||||
deploy so drift shows up in the log.
|
||||
|
||||
## Bind addresses — decided 2026-10-26
|
||||
|
||||
The container publishes on two explicit addresses and nothing else:
|
||||
|
||||
| Address | Why |
|
||||
|---|---|
|
||||
| `127.0.0.1:8096` | `deploy.sh`'s health gate and any check made on `.13` itself |
|
||||
| `192.168.20.13:8096` | the LAN address Caddy on `.35` proxies to (`docs/phase-3-deploy.md` §3.3) |
|
||||
|
||||
A wildcard bind (`0.0.0.0`) is still forbidden: Caddy on `.35` stays the only
|
||||
public listener. The phase document asked for loopback only, but a loopback-only
|
||||
listener is unreachable from `.35`; Sam resolved the contradiction on AUD-133
|
||||
with "A - dual bind: 127.0.0.1:8096 and 192.168.20.13:8096". `APP_LAN_IP`
|
||||
overrides the LAN address (default `192.168.20.13`); `deploy.sh --lan-ip ADDR`
|
||||
sets it for one run. Both `deploy.sh` and `rehearse.sh` assert that the LAN
|
||||
address answers, not just loopback.
|
||||
|
||||
## Caddy
|
||||
|
||||
`docs/phase-3-deploy.md` §3.3 holds the block for `.35`. It is additive, applied
|
||||
with `caddy reload` (never a restart), and **Sam applies it** — see
|
||||
`docs/phase-3-evidence.md` for the open bind-address question that decides
|
||||
whether that block points at `192.168.20.13:8096` or at `.13`'s Caddy.
|
||||
with `caddy reload` (never a restart), and **Sam applies it**. The block proxies
|
||||
to `192.168.20.13:8096`, which is why the container publishes on that address as
|
||||
well as loopback (see *Bind addresses* above).
|
||||
|
||||
Reference in New Issue
Block a user