fix(deploy): detect the actually-live blue/green slot, stop nginx-sync clobbering the upstream
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 30s
CI / tests-unit (push) Successful in 1m40s
CI / tests-integration (push) Successful in 1m42s
CI / tests-ui (push) Successful in 2m28s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m5s

- ci-deploy.sh: read_active_port() now probes both slots on /api/health and
  picks the one that really answers; the upstream file only serves as a
  fallback when zero or both slots respond. A stray 'docker compose up' (or a
  clobbered snippet) can no longer derail the next deploy's cutover.
- nginx-sync.sh: cms_upstream_servers.conf is runtime-owned by ci-deploy.sh;
  only seed it when missing, never overwrite what a deploy wrote. This is the
  root cause of tonight's 502: a nginx-sync run reset the snippet (written to
  green:3003 by the last cutover) back to the dead slot A:3002.
- cms_upstream_servers.conf: restore the fresh-host seed default to slot A.
This commit is contained in:
openhands committed 2026-09-28 23:38:22 +02:00
1 parent 90b65c92a2
commit 7507c3b55c
3 files changed
+27 -5

No files matched your search

+1 -1
View File
@@ -1,2 +1,2 @@
# Default; ci-deploy.sh (blue/green) herschrijft dit bestand bij elke switch. # Default; ci-deploy.sh (blue/green) herschrijft dit bestand bij elke switch.
server 127.0.0.1:3003; server 127.0.0.1:3002;
+17 -3
View File
@@ -85,10 +85,24 @@ detect_blue_green() {
return 0 return 0
} }
# Op welke poort verwerkt nginx nu verkeer? Onbekend (of geen bestand) betekent # Welke poort is op dit moment ÉCHT live? Kijk niet naar het upstream-bestand
# slot A, zodat de allereerste release op 3002 terechtkomt. # (dat kan door een losse `docker compose up` zijn ingehaald en naar een dood
# slot wijzen), maar test welk slot werkelijk antwoordt op /api/health. Alleen
# in een dubbelzinnige situatie (geen óf beide slots gezond) valt het script
# terug op de huidige nginx-pointer; onbekend = slot A (eerste release op 3002).
read_active_port() { read_active_port() {
local port="" local live="" port="" result=""
local count=0
for port in "$slot_a_port" "$slot_b_port"; do
if curl -sf --max-time 3 "http://127.0.0.1:$port/api/health" | grep -q '"database":true'; then
live="$live $port"
fi
done
for port in $live; do count=$((count + 1)); result="$port"; done
if [ "$count" -eq 1 ]; then
printf '%s' "$result"
return 0
fi
port="$(grep -oE '127\.0\.0\.1:[0-9]+' "$upstream_file" 2>/dev/null | head -1 | cut -d: -f2 || true)" port="$(grep -oE '127\.0\.0\.1:[0-9]+' "$upstream_file" 2>/dev/null | head -1 | cut -d: -f2 || true)"
case "$port" in case "$port" in
"$slot_b_port") printf '%s' "$slot_b_port" ;; "$slot_b_port") printf '%s' "$slot_b_port" ;;
+9 -1
View File
@@ -18,6 +18,8 @@
# nginx-cms.conf -> /etc/nginx/sites-available/cms.conf # nginx-cms.conf -> /etc/nginx/sites-available/cms.conf
# cloudflare-ips.conf -> /etc/nginx/conf.d/cloudflare-ips.conf # cloudflare-ips.conf -> /etc/nginx/conf.d/cloudflare-ips.conf
# cms_upstream_servers.conf -> /etc/nginx/snippets/cms_upstream_servers.conf # cms_upstream_servers.conf -> /etc/nginx/snippets/cms_upstream_servers.conf
# (seed alleen als het bestand ontbreekt; zodra het bestaat is het runtime
# eigendom van scripts/ci-deploy.sh en wordt het hier nooit overschreven)
# symlink sites-enabled/cms.conf -> ../sites-available/cms.conf # symlink sites-enabled/cms.conf -> ../sites-available/cms.conf
set -euo pipefail set -euo pipefail
@@ -68,7 +70,13 @@ if install_file "$PROXY_DIR/nginx.conf" "$NGINX_DIR/nginx.conf"; then changed=1;
if install_file "$PROXY_DIR/nginx-mime.types" "$NGINX_DIR/mime.types"; then changed=1; fi if install_file "$PROXY_DIR/nginx-mime.types" "$NGINX_DIR/mime.types"; then changed=1; fi
if install_file "$PROXY_DIR/nginx-cms.conf" "$NGINX_DIR/sites-available/cms.conf"; then changed=1; fi if install_file "$PROXY_DIR/nginx-cms.conf" "$NGINX_DIR/sites-available/cms.conf"; then changed=1; fi
if install_file "$PROXY_DIR/cloudflare-ips.conf" "$NGINX_DIR/conf.d/cloudflare-ips.conf"; then changed=1; fi if install_file "$PROXY_DIR/cloudflare-ips.conf" "$NGINX_DIR/conf.d/cloudflare-ips.conf"; then changed=1; fi
if install_file "$PROXY_DIR/cms_upstream_servers.conf" "$NGINX_DIR/snippets/cms_upstream_servers.conf"; then changed=1; fi # De upstream-snippet is runtime-eigendom van ci-deploy.sh (blue/green): alleen
# aanmaken op een verse host, nooit overschrijven wat een deploy heeft gezet.
if [[ -f "$NGINX_DIR/snippets/cms_upstream_servers.conf" ]]; then
echo "= $NGINX_DIR/snippets/cms_upstream_servers.conf managed by ci-deploy.sh (untouched)"
else
if install_file "$PROXY_DIR/cms_upstream_servers.conf" "$NGINX_DIR/snippets/cms_upstream_servers.conf"; then changed=1; fi
fi
if [[ ! -f "$NGINX_DIR/sites-enabled/cms.conf" ]]; then if [[ ! -f "$NGINX_DIR/sites-enabled/cms.conf" ]]; then
if [[ "$MODE" == "check" ]]; then if [[ "$MODE" == "check" ]]; then