deploy.sh: incoming image tag wins over .image-tags.env; health via container healthcheck
Two bugs surfaced wiring dev auto-deploy: 1. Sourcing .image-tags.env clobbered the caller's incoming *_IMAGE_TAG. The first backend-only deploy persists FRONTEND_IMAGE_TAG=local (sibling unknown); the next frontend deploy then sourced that and pulled :local -> 'manifest unknown'. Now the incoming env is captured before sourcing and re-applied. 2. Health-checked services via a host-port curl, but the dev overlay leaves the frontend port unpublished (reached via the backend proxy) -> false failure. Now polls each container's own HEALTHCHECK status via docker inspect.
This commit is contained in:
parent
418f4e0631
commit
59e7517747
1 changed files with 24 additions and 10 deletions
|
|
@ -114,9 +114,19 @@ export REGISTRY_HOST BACKEND_IMAGE_PATH FRONTEND_IMAGE_PATH
|
||||||
# service being deployed then overrides its line below. This file is untracked
|
# service being deployed then overrides its line below. This file is untracked
|
||||||
# (see .gitignore), so `git reset --hard` above leaves it in place.
|
# (see .gitignore), so `git reset --hard` above leaves it in place.
|
||||||
TAGS_FILE="$APP_DIR/deploy/.image-tags.env"
|
TAGS_FILE="$APP_DIR/deploy/.image-tags.env"
|
||||||
|
# Capture the tags the caller explicitly passed BEFORE sourcing -- they must
|
||||||
|
# WIN. The file only supplies the *sibling's* last-known tag; sourcing it
|
||||||
|
# unconditionally would clobber an incoming tag (e.g. a frontend deploy whose
|
||||||
|
# FRONTEND_IMAGE_TAG got overwritten by the stale `local` the first backend-only
|
||||||
|
# deploy persisted for the not-yet-known sibling -> pull `:local` -> "manifest
|
||||||
|
# unknown"). So source for the sibling, then re-apply the caller's own value.
|
||||||
|
_incoming_backend="${BACKEND_IMAGE_TAG:-}"
|
||||||
|
_incoming_frontend="${FRONTEND_IMAGE_TAG:-}"
|
||||||
if [ -f "$TAGS_FILE" ]; then
|
if [ -f "$TAGS_FILE" ]; then
|
||||||
set -a; . "$TAGS_FILE"; set +a
|
set -a; . "$TAGS_FILE"; set +a
|
||||||
fi
|
fi
|
||||||
|
[ -n "$_incoming_backend" ] && BACKEND_IMAGE_TAG="$_incoming_backend"
|
||||||
|
[ -n "$_incoming_frontend" ] && FRONTEND_IMAGE_TAG="$_incoming_frontend"
|
||||||
|
|
||||||
# Guard: the service(s) being rolled MUST have a concrete tag supplied now (the
|
# Guard: the service(s) being rolled MUST have a concrete tag supplied now (the
|
||||||
# sibling's may come from the persisted file). `all` needs both.
|
# sibling's may come from the persisted file). `all` needs both.
|
||||||
|
|
@ -207,21 +217,25 @@ EOF
|
||||||
# Health check the service(s) we rolled: backend on 8137, frontend on 8080.
|
# Health check the service(s) we rolled: backend on 8137, frontend on 8080.
|
||||||
# (For `all`, backend's `/` serving is the readiness signal the old script used
|
# (For `all`, backend's `/` serving is the readiness signal the old script used
|
||||||
# and the frontend depends_on backend anyway.)
|
# and the frontend depends_on backend anyway.)
|
||||||
declare -A HEALTH_PORTS=( [backend]=8137 [frontend]=8080 )
|
# Health via each container's own HEALTHCHECK (docker inspect), NOT a host-port
|
||||||
|
# curl: the dev overlay leaves the frontend port UNpublished (reached through the
|
||||||
|
# backend's _proxy_to_frontend), so a localhost:8080 curl spuriously fails there.
|
||||||
|
# Both images HEALTHCHECK-curl /healthz internally, so this works published or not.
|
||||||
health_ok=1
|
health_ok=1
|
||||||
for svc in "${TARGETS[@]}"; do
|
for svc in "${TARGETS[@]}"; do
|
||||||
port="${HEALTH_PORTS[$svc]}"
|
cid=$(docker compose ps -q "$svc" 2>/dev/null)
|
||||||
url="http://127.0.0.1:${port}/healthz"
|
echo "==> Health check: $svc (container health)"
|
||||||
echo "==> Health check: $svc ($url)"
|
ok=0; st=unknown
|
||||||
ok=0
|
for i in $(seq 1 40); do
|
||||||
for i in $(seq 1 30); do
|
st=$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "$cid" 2>/dev/null || echo gone)
|
||||||
if curl -fsS -o /dev/null "$url"; then ok=1; break; fi
|
[ "$st" = healthy ] && { ok=1; break; }
|
||||||
sleep 1
|
if [ "$st" = none ] && [ "$(docker inspect --format '{{.State.Status}}' "$cid" 2>/dev/null)" = running ]; then ok=1; break; fi
|
||||||
|
sleep 2
|
||||||
done
|
done
|
||||||
if [ "$ok" = 1 ]; then
|
if [ "$ok" = 1 ]; then
|
||||||
echo "==> OK: $svc is serving"
|
echo "==> OK: $svc is healthy"
|
||||||
else
|
else
|
||||||
echo "!! Health check failed for $svc ($url)" >&2
|
echo "!! Health check failed for $svc (status=$st)" >&2
|
||||||
health_ok=0
|
health_ok=0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue