124 lines
3.1 KiB
Bash
124 lines
3.1 KiB
Bash
#!/bin/sh
|
||
# yh_nginx:1) 等 web/admin/api 就绪 2) 从 /etc/resolv.conf 取 nameserver 写入 resolver
|
||
# 3) 由 tpl 生成 default.conf(变量 proxy_pass),避免 Podman 在「探测已通过」后仍 host not found in upstream "api"。
|
||
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
|
||
}
|
||
|
||
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_ok() {
|
||
host="$1"
|
||
port="$2"
|
||
path="${3:-/}"
|
||
if ! command -v wget >/dev/null 2>&1; then
|
||
return 1
|
||
fi
|
||
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
|
||
if upstream_ok web 80 / && upstream_ok admin 80 / && upstream_ok api 8088 /api/health; then
|
||
break
|
||
fi
|
||
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
|
||
|
||
if [ "$n" -ge "$MAX" ]; then
|
||
echo "yh_nginx: timeout after ${MAX}s." >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "yh_nginx: upstream OK, generating nginx config..."
|
||
|
||
# 与容器内实际 DNS 一致(Podman 常非 127.0.0.11);多个 nameserver 空格分隔(兼容 IPv6)
|
||
NSLINE=""
|
||
while read -r line; do
|
||
case "$line" in
|
||
nameserver\ *)
|
||
ip=${line#nameserver }
|
||
ip=${ip%%#*}
|
||
# trim
|
||
ip=$(echo "$ip" | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||
[ -z "$ip" ] && continue
|
||
NSLINE="${NSLINE}${NSLINE:+ }${ip}"
|
||
;;
|
||
esac
|
||
done < /etc/resolv.conf
|
||
|
||
if [ -z "$NSLINE" ]; then
|
||
NSLINE="127.0.0.11"
|
||
echo "yh_nginx: warn: no nameserver in resolv.conf, fallback ${NSLINE}" >&2
|
||
else
|
||
echo "yh_nginx: resolver from resolv.conf: ${NSLINE}" >&2
|
||
fi
|
||
|
||
# Docker compose 服务名由网桥内置 DNS(通常 127.0.0.11)解析;仅用宿主机 DNS 会间歇「could not be resolved」→502
|
||
case "$NSLINE" in
|
||
*127.0.0.11*) ;;
|
||
*) NSLINE="127.0.0.11 ${NSLINE}"; echo "yh_nginx: prepended 127.0.0.11 for compose DNS: ${NSLINE}" >&2 ;;
|
||
esac
|
||
|
||
if [ ! -r /yuheng.docker.conf.tpl ]; then
|
||
echo "yh_nginx: error: /yuheng.docker.conf.tpl not mounted" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# sed 用 | 分隔,避免 IPv6 里 : 干扰(当前仍支持多 IPv4 nameserver)
|
||
sed "s|@@NGINX_RESOLVER@@|${NSLINE}|g" /yuheng.docker.conf.tpl > /etc/nginx/conf.d/default.conf
|
||
|
||
nginx -t
|
||
echo "yh_nginx: starting nginx..."
|
||
exec nginx -g 'daemon off;'
|