#!/bin/sh # 供 yh_nginx 容器:在官方 entrypoint 之前等待 Compose/Podman 网络内 web/admin/api 可访问。 # 解决 1) 启动瞬间 host not found;2) Podman 无 127.0.0.11 时勿用 resolver+变量 proxy_pass(否则 502/超时)。 # # 探测顺序:HTTP(wget) → TCP(nc) → ICMP(ping)。部分环境禁 ping 或 busybox wget 异常时,nc 仍可判定「能连上端口」。 set -e MAX="${NGINX_WAIT_UPSTREAM_SEC:-120}" DEBUG="${NGINX_WAIT_DEBUG:-0}" log() { if [ "$DEBUG" = "1" ] || [ "$DEBUG" = "true" ]; then echo "yh_nginx(wait): $*" >&2 fi } echo "yh_nginx: waiting for upstream (web:80 admin:80 api:8088), max ${MAX}s..." ping_one() { host="$1" if ping -c1 -W2 "$host" >/dev/null 2>&1; then return 0 fi ping -c1 -w3 "$host" >/dev/null 2>&1 } # 仅测端口是否打开(不依赖 HTTP 状态码) tcp_open() { host="$1" port="$2" if ! command -v nc >/dev/null 2>&1; then return 1 fi nc -z -w3 "$host" "$port" 2>/dev/null } # HTTP 成功(2xx/3xx);busybox wget 遇 404 会非 0,故 API 必须用会返回 200 的路径 http_ok() { host="$1" port="$2" path="${3:-/}" if ! command -v wget >/dev/null 2>&1; then return 1 fi # -T:秒;部分镜像仅支持短选项 if wget -q -O/dev/null -T 5 "http://${host}:${port}${path}" 2>/dev/null; then return 0 fi return 1 } upstream_ok() { host="$1" port="$2" path="${3:-/}" if http_ok "$host" "$port" "$path"; then log "http OK ${host}:${port}${path}" return 0 fi if tcp_open "$host" "$port"; then log "tcp OK ${host}:${port}" return 0 fi if ping_one "$host"; then log "ping OK $host (HTTP/TCP 未验证,仅 DNS/L3)" return 0 fi return 1 } n=0 while [ "$n" -lt "$MAX" ]; do # api 用 /api/health 保证 wget 为 200 if upstream_ok web 80 / && upstream_ok admin 80 / && upstream_ok api 8088 /api/health; then echo "yh_nginx: upstream OK, starting nginx..." exec /docker-entrypoint.sh nginx -g 'daemon off;' fi # 每 15s 打一行,便于 docker logs 排查 if [ "$n" -gt 0 ] && [ $((n % 15)) -eq 0 ]; then echo "yh_nginx: still waiting... ${n}s / max ${MAX}s (web admin api)" >&2 fi n=$((n + 1)) sleep 1 done echo "yh_nginx: timeout after ${MAX}s. 调试: docker logs yh_nginx;或临时 export NGINX_WAIT_UPSTREAM_SEC=300" >&2 echo "yh_nginx: 可设 NGINX_WAIT_DEBUG=1 查看每步探测;确认 yh_api 内 curl -s http://127.0.0.1:8088/api/health" >&2 exit 1