fix(deploy): 入口自检改为域名无关(脱敏把探测域名换成了占位符导致误判失败)

真实部署失败原因:脱敏时把仓库里所有 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 未定义同类错误),本次一并纠正并改为先定义后使用。
This commit is contained in:
HomeDash Bot
2026-09-12 10:43:13 +08:00
parent dbdfe0faef
commit b850a478fe

View File

@ -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)"