From 7507c3b55c5ffa05579f6f37c1aff962707faa58 Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 28 Sep 2026 23:38:22 +0200 Subject: [PATCH] fix(deploy): detect the actually-live blue/green slot, stop nginx-sync clobbering the upstream - 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. --- deployment/proxy/cms_upstream_servers.conf | 2 +- scripts/ci-deploy.sh | 20 +++++++++++++++++--- scripts/nginx-sync.sh | 10 +++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/deployment/proxy/cms_upstream_servers.conf b/deployment/proxy/cms_upstream_servers.conf index ec033ec2..786b1856 100644 --- a/deployment/proxy/cms_upstream_servers.conf +++ b/deployment/proxy/cms_upstream_servers.conf @@ -1,2 +1,2 @@ # Default; ci-deploy.sh (blue/green) herschrijft dit bestand bij elke switch. -server 127.0.0.1:3003; \ No newline at end of file +server 127.0.0.1:3002; \ No newline at end of file diff --git a/scripts/ci-deploy.sh b/scripts/ci-deploy.sh index 1c06b299..d2d20956 100644 --- a/scripts/ci-deploy.sh +++ b/scripts/ci-deploy.sh @@ -85,10 +85,24 @@ detect_blue_green() { return 0 } -# Op welke poort verwerkt nginx nu verkeer? Onbekend (of geen bestand) betekent -# slot A, zodat de allereerste release op 3002 terechtkomt. +# Welke poort is op dit moment ÉCHT live? Kijk niet naar het upstream-bestand +# (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() { - 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)" case "$port" in "$slot_b_port") printf '%s' "$slot_b_port" ;; diff --git a/scripts/nginx-sync.sh b/scripts/nginx-sync.sh index 39a6df8c..9bc673d2 100755 --- a/scripts/nginx-sync.sh +++ b/scripts/nginx-sync.sh @@ -18,6 +18,8 @@ # nginx-cms.conf -> /etc/nginx/sites-available/cms.conf # cloudflare-ips.conf -> /etc/nginx/conf.d/cloudflare-ips.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 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-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/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 [[ "$MODE" == "check" ]]; then