fix(nginx): Podman 下弃用 127.0.0.11 resolver,启动前等待上游可达
Made-with: Cursor
This commit is contained in:
@@ -54,7 +54,10 @@ services:
|
|||||||
container_name: yh_nginx
|
container_name: yh_nginx
|
||||||
ports:
|
ports:
|
||||||
- "443:443"
|
- "443:443"
|
||||||
|
# Podman 无 Docker 的 127.0.0.11:勿在 nginx 里用 resolver+变量 proxy_pass。先等 web/admin/api 可解析再启动 nginx。
|
||||||
|
entrypoint: ["/bin/sh", "/nginx-entrypoint-wait-dns.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
|
- ./scripts/nginx-entrypoint-wait-dns.sh:/nginx-entrypoint-wait-dns.sh:ro
|
||||||
- ./nginx/yuheng.docker.conf:/etc/nginx/conf.d/default.conf:ro
|
- ./nginx/yuheng.docker.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
- /etc/ssl/yh_web/yuheng.yuxindazhineng.com:/etc/ssl/yh_web/yuheng.yuxindazhineng.com:ro
|
- /etc/ssl/yh_web/yuheng.yuxindazhineng.com:/etc/ssl/yh_web/yuheng.yuxindazhineng.com:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# 供 docker-compose 中 nginx 使用:仅监听 443,反代到 api/web/admin;证书挂载到 /etc/ssl/yh_web/yuheng.yuxindazhineng.com/
|
# 供 docker-compose 中 nginx 使用:仅监听 443,反代到 api/web/admin;证书挂载到 /etc/ssl/yh_web/yuheng.yuxindazhineng.com/
|
||||||
#
|
#
|
||||||
# 使用 resolver + 变量形式的 proxy_pass:避免启动时同步解析 upstream 主机名失败
|
# 使用静态 proxy_pass(依赖 Compose/Podman 内置 DNS)。容器启动顺序由 depends_on + docker-compose.yml
|
||||||
#(Docker/Podman 在 yh_nginx 刚起来时,内置 DNS 里可能还没有 web/admin/api,会报 host not found in upstream "web")
|
# 中 entrypoint 等待脚本保证:解析就绪后再启动 nginx,避免「host not found in upstream」。
|
||||||
|
# 勿配合 127.0.0.11 resolver + 变量 proxy_pass 用于 Podman:无该 DNS 时会导致长时间超时 → 502。
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
@@ -10,9 +11,6 @@ server {
|
|||||||
server_name yuheng.yuxindazhineng.com;
|
server_name yuheng.yuxindazhineng.com;
|
||||||
client_max_body_size 800m;
|
client_max_body_size 800m;
|
||||||
|
|
||||||
# Docker Compose 内置 DNS;若 Podman 下首包 502,可在此增加本网关 IP(podman network inspect 查看)
|
|
||||||
resolver 127.0.0.11 valid=10s ipv6=off;
|
|
||||||
|
|
||||||
ssl_certificate /etc/ssl/yh_web/yuheng.yuxindazhineng.com/fullchain.pem;
|
ssl_certificate /etc/ssl/yh_web/yuheng.yuxindazhineng.com/fullchain.pem;
|
||||||
ssl_certificate_key /etc/ssl/yh_web/yuheng.yuxindazhineng.com/privkey.pem;
|
ssl_certificate_key /etc/ssl/yh_web/yuheng.yuxindazhineng.com/privkey.pem;
|
||||||
ssl_session_timeout 1d;
|
ssl_session_timeout 1d;
|
||||||
@@ -21,8 +19,7 @@ server {
|
|||||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
set $upstream_web web;
|
proxy_pass http://web:80;
|
||||||
proxy_pass http://$upstream_web:80;
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
@@ -31,8 +28,7 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
location /admin/ {
|
location /admin/ {
|
||||||
set $upstream_admin admin;
|
proxy_pass http://admin:80/;
|
||||||
proxy_pass http://$upstream_admin:80/;
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
@@ -42,8 +38,7 @@ server {
|
|||||||
|
|
||||||
# 不要用尾部斜杠,否则 /api/health 会变成 /health,而后端注册的是 /api/health
|
# 不要用尾部斜杠,否则 /api/health 会变成 /health,而后端注册的是 /api/health
|
||||||
location /api/ {
|
location /api/ {
|
||||||
set $upstream_api api;
|
proxy_pass http://api:8088;
|
||||||
proxy_pass http://$upstream_api:8088;
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|||||||
38
scripts/nginx-entrypoint-wait-dns.sh
Normal file
38
scripts/nginx-entrypoint-wait-dns.sh
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# 供 yh_nginx 容器:在官方 entrypoint 之前等待 Compose/Podman 网络内 web/admin/api 可访问。
|
||||||
|
# 解决 1) 启动瞬间 host not found;2) Podman 无 127.0.0.11 时勿用 resolver+变量 proxy_pass(否则 502/超时)。
|
||||||
|
set -e
|
||||||
|
MAX="${NGINX_WAIT_UPSTREAM_SEC:-90}"
|
||||||
|
echo "yh_nginx: waiting for upstream (web:80 admin:80 api:8088), max ${MAX}s..."
|
||||||
|
|
||||||
|
# 优先 HTTP 探测(ICMP 在部分环境被禁);无 wget 时用 ping
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream_ok() {
|
||||||
|
host="$1"
|
||||||
|
port="$2"
|
||||||
|
path="${3:-/}"
|
||||||
|
if command -v wget >/dev/null 2>&1; then
|
||||||
|
wget -q -O/dev/null -T 3 "http://${host}:${port}${path}" 2>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
ping_one "$host"
|
||||||
|
}
|
||||||
|
|
||||||
|
n=0
|
||||||
|
while [ "$n" -lt "$MAX" ]; do
|
||||||
|
# api 根路径常为 404,用 /api/health(与 yuheng.docker.conf 注释一致)
|
||||||
|
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
|
||||||
|
n=$((n + 1))
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "yh_nginx: timeout waiting for web/admin/api (check 容器是否在同一网络、api 是否监听 8088)" >&2
|
||||||
|
exit 1
|
||||||
Reference in New Issue
Block a user