From b850a478fe1b58aebaa9377184633ce265d081cf Mon Sep 17 00:00:00 2001 From: HomeDash Bot Date: Sat, 12 Sep 2026 10:43:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(deploy):=20=E5=85=A5=E5=8F=A3=E8=87=AA?= =?UTF-8?q?=E6=A3=80=E6=94=B9=E4=B8=BA=E5=9F=9F=E5=90=8D=E6=97=A0=E5=85=B3?= =?UTF-8?q?=EF=BC=88=E8=84=B1=E6=95=8F=E6=8A=8A=E6=8E=A2=E6=B5=8B=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E6=8D=A2=E6=88=90=E4=BA=86=E5=8D=A0=E4=BD=8D=E7=AC=A6?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E8=AF=AF=E5=88=A4=E5=A4=B1=E8=B4=A5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真实部署失败原因:脱敏时把仓库里所有 example.com 换成 example.com,连 deploy/zd-host.sh 的三个入口自检探测域名也一起换了 → 自检去探测 dashy.example.com(用户路由表里不存在)→ 404 → 判定失败并回滚。 修复: - 探测域名默认取数据卷 gateway.yml 路由表第一条的 host(或 NAVI_CHECK_HOST 显式指定), 不再把任何具体域名写进脚本 - 已配置域名接受 200/302(门户 200、受保护 302 都算正常); 000(未监听)/404(不在路由表)/5xx 才算失败;未知域名仍必须 404;3081 必须 302 - apply 后先轮询等待 reload 就绪再探测(异步 reload 会误判) 另修复上一轮引入的隐患:等待循环引用了脚本里不存在的 $CHECK_HOST/$ENTRY_PORT, set -u 下会直接崩(与第一轮 HOST 未定义同类错误),本次一并纠正并改为先定义后使用。 --- deploy/zd-host.sh | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/deploy/zd-host.sh b/deploy/zd-host.sh index db83122..1e2979b 100644 --- a/deploy/zd-host.sh +++ b/deploy/zd-host.sh @@ -156,20 +156,33 @@ w200 "http://127.0.0.1:18080/healthz" w200 "http://127.0.0.1:18080/conf.yml" w200 "http://127.0.0.1:18080/admin" -# apply 触发的 nginx reload 是异步的:不等就绪直接探测会拿到 404, -# 造成"明明升级成功却判失败"(本次真实踩到,与 README 接口注意事项第 4 条同因)。 +# 入口自检:探测域名不写死(脱敏时曾把真实域名换成占位符,导致自检去探测 +# 一个路由表里不存在的域名而误判失败)。默认取路由表第一条的 host, +# 也可用 NAVI_CHECK_HOST 指定。apply 触发的 reload 是异步的,先等就绪。 +CHECK_HOST="${NAVI_CHECK_HOST:-}" +if [ -z "$CHECK_HOST" ]; then + CHECK_HOST=$(grep -m1 'host:' "$DATA_DIR/gateway.yml" 2>/dev/null | sed 's/.*host:[[:space:]]*//' | tr -d '"'"'"' | tr -d '\r') +fi +[ -n "$CHECK_HOST" ] || { echo "!! 无法确定自检域名:请传 NAVI_CHECK_HOST=<某个已配置的域名>" >&2; false; } +echo " 自检探测域名: $CHECK_HOST" + for _w in $(seq 1 20); do - _c=$(curl -sk -o /dev/null -w "%{http_code}" -m 3 --resolve "$CHECK_HOST:${ENTRY_PORT:-3080}:127.0.0.1" \ - "https://$CHECK_HOST:${ENTRY_PORT:-3080}/" 2>/dev/null || echo 000) + _c=$(curl -sk -o /dev/null -w '%{http_code}' -m 3 --resolve "$CHECK_HOST:3080:127.0.0.1" \ + "https://$CHECK_HOST:3080/" 2>/dev/null || echo 000) [ "$_c" != "000" ] && break sleep 0.5 done -# 入口自检:受保护域名应 302、公开域名应非 5xx、未知域名应 404(自定义页) -CODE=$(curl -sk -o /dev/null -w '%{http_code}' -m 8 --resolve dashy.example.com:3080:127.0.0.1 https://dashy.example.com:3080/conf.yml) -[ "$CODE" = "302" ] || { echo "!! 受保护域名应 302,实际 $CODE" >&2; false; } -CODE=$(curl -sk -o /dev/null -w '%{http_code}' -m 8 --resolve nobody.test:3080:127.0.0.1 https://nobody.test:3080/) + +# 已配置的域名必须可服务:门户可能是 200,受保护的是 302 —— 两者都算正常; +# 000(没监听)/404(不在路由表)/5xx(上游或配置坏了)都算失败。 +CODE=$(curl -sk -o /dev/null -w '%{http_code}' -m 8 --resolve "$CHECK_HOST:3080:127.0.0.1" "https://$CHECK_HOST:3080/") +case "$CODE" in + 200|302) echo " 已配置域名 $CHECK_HOST → $CODE" ;; + *) echo "!! 已配置域名 $CHECK_HOST 应 200/302,实际 $CODE" >&2; false ;; +esac +CODE=$(curl -sk -o /dev/null -w '%{http_code}' -m 8 --resolve nobody.invalid:3080:127.0.0.1 https://nobody.invalid:3080/) [ "$CODE" = "404" ] || { echo "!! 未知域名应 404,实际 $CODE" >&2; false; } -CODE=$(curl -s -o /dev/null -w '%{http_code}' -m 8 -H 'Host: dashy.example.com' http://127.0.0.1:3081/) +CODE=$(curl -s -o /dev/null -w '%{http_code}' -m 8 -H "Host: $CHECK_HOST" http://127.0.0.1:3081/) [ "$CODE" = "302" ] || { echo "!! HTTP 入口应 302 跳转,实际 $CODE" >&2; false; } echo " 入口自检通过(3080/3081)"