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:
@@ -28,6 +28,10 @@ DEFAULT_ROOT="/home/sam/deployment/resume"
|
||||
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ROOT="${DEPLOY_ROOT:-$DEFAULT_ROOT}"
|
||||
PORT="${APP_PORT:-$DEFAULT_PORT}"
|
||||
# Caddy on .35 proxies to this host's LAN address (phase doc §3.3), so the
|
||||
# container publishes on loopback *and* on that address. Sam's decision on
|
||||
# AUD-133, 2026-10-26: "A - dual bind: 127.0.0.1:8096 and 192.168.20.13:8096".
|
||||
LAN_IP="${APP_LAN_IP:-192.168.20.13}"
|
||||
DO_ROLLBACK=0
|
||||
HEALTH_TIMEOUT="${HEALTH_TIMEOUT:-40}"
|
||||
|
||||
@@ -39,6 +43,7 @@ Usage: deploy.sh [options]
|
||||
--source DIR build from DIR instead of the repo this script lives in
|
||||
--root DIR release root (default /home/sam/deployment/resume)
|
||||
--port N app port (default 8096)
|
||||
--lan-ip ADDR LAN address the container also publishes on (default 192.168.20.13)
|
||||
--health-timeout N seconds to wait for /healthz (default 40)
|
||||
-h, --help this text
|
||||
|
||||
@@ -46,6 +51,7 @@ Environment:
|
||||
GO path to the go toolchain (auto-detected, incl. /nix/store)
|
||||
DEPLOY_ROOT same as --root
|
||||
APP_PORT same as --port
|
||||
APP_LAN_IP same as --lan-ip
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -55,6 +61,7 @@ while [[ $# -gt 0 ]]; do
|
||||
--source) SRC_DIR="$(cd "$2" && pwd)"; shift 2 ;;
|
||||
--root) ROOT="$2"; shift 2 ;;
|
||||
--port) PORT="$2"; shift 2 ;;
|
||||
--lan-ip) LAN_IP="$2"; shift 2 ;;
|
||||
--health-timeout) HEALTH_TIMEOUT="$2"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "unknown argument: $1" >&2; usage >&2; exit 2 ;;
|
||||
@@ -110,6 +117,17 @@ check_health() {
|
||||
fi
|
||||
fi
|
||||
log "health: $url -> 200"
|
||||
|
||||
# The container also publishes on the LAN address because that is what Caddy
|
||||
# on .35 proxies to. A loopback-only success would be a site nobody can reach.
|
||||
local lan_url lan_code
|
||||
lan_url="http://${LAN_IP}:${PORT}/healthz"
|
||||
lan_code=$(curl -s --max-time 3 -o /dev/null -w '%{http_code}' "$lan_url" 2>/dev/null || true)
|
||||
if [[ "$lan_code" != "200" ]]; then
|
||||
log "health: $lan_url -> HTTP ${lan_code:-none} (LAN bind missing?)"
|
||||
return 1
|
||||
fi
|
||||
log "health: $lan_url -> 200"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -218,7 +236,7 @@ do_deploy() {
|
||||
echo "built_on=$(hostname)"
|
||||
echo "binary_sha256=$(sha256sum "$release/bin/server" | cut -d' ' -f1)"
|
||||
} > "$release/manifest.txt"
|
||||
printf 'APP_VERSION=%s\nAPP_PORT=%s\n' "$ts" "$PORT" > "$release/.env"
|
||||
printf 'APP_VERSION=%s\nAPP_PORT=%s\nAPP_LAN_IP=%s\n' "$ts" "$PORT" "$LAN_IP" > "$release/.env"
|
||||
|
||||
# 3. Runtime image, tagged with this release.
|
||||
log "deploy: docker build resume/app:$ts"
|
||||
|
||||
Reference in New Issue
Block a user