隔离边界:只使用本机 Docker Compose 创建的 lab-nginx 项目,端口绑定在 127.0.0.1:8080;不修改宿主机 Nginx,不连接任何生产上游。所有文件放在 /tmp/lab-nginx。
docker version --format '{{.ServerVersion}}' && docker compose version
mkdir -p /tmp/lab-nginx
cat > /tmp/lab-nginx/docker-compose.yml <<'EOF'
name: lab-nginx
services:
app:
image: nginx:1.27-alpine
edge:
image: nginx:1.27-alpine
ports: ["127.0.0.1:8080:80"]
volumes: ["./edge.conf:/etc/nginx/conf.d/default.conf:ro"]
depends_on: [app]
EOF
cat > /tmp/lab-nginx/edge.conf <<'EOF'
server {
listen 80;
location / { proxy_pass http://app:80; }
}
EOF
docker compose -f /tmp/lab-nginx/docker-compose.yml up -d
for i in $(seq 1 30); do
curl -s -o /dev/null http://127.0.0.1:8080/ && break
sleep 2
done
先停掉上游应用,制造“进程未启动”:
docker compose -f /tmp/lab-nginx/docker-compose.yml stop app
sleep 2
curl -s -o /dev/null -w 'stopped_code=%{http_code}\n' http://127.0.0.1:8080/
再恢复 app,把 upstream 端口从 80 改成 8080,模拟配置错误:
docker compose -f /tmp/lab-nginx/docker-compose.yml start app
sed -i 's|http://app:80|http://app:8080|' /tmp/lab-nginx/edge.conf
docker compose -f /tmp/lab-nginx/docker-compose.yml exec -T edge nginx -s reload
sleep 2
curl -s -o /dev/null -w 'bad_port_code=%{http_code}\n' http://127.0.0.1:8080/
docker compose -f /tmp/lab-nginx/docker-compose.yml logs --no-color edge | tail -30
docker compose -f /tmp/lab-nginx/docker-compose.yml ps
预期 stopped_code=502、bad_port_code=502,响应首行是 HTTP/1.1 502 Bad Gateway。error log 中出现 connect() failed (111: Connection refused) while connecting to upstream;停 app 时 upstream 是 http://<ip>:80/,改端口后是 http://<ip>:8080/。access log 中对应请求的状态码为 502。
从 edge 容器内部确认上游是否可达:
docker compose -f /tmp/lab-nginx/docker-compose.yml exec -T edge \
sh -c 'wget -qO- --timeout=2 http://app:80 | head -1'
docker compose -f /tmp/lab-nginx/docker-compose.yml exec -T edge \
sh -c 'wget -qO- --timeout=2 http://app:8080' ; echo "exit=$?"
当前 app 已恢复时,第一条返回 Nginx 欢迎页,第二条连接失败,说明网络和 DNS 正常,问题在 upstream 端口。若 app 处于停止状态,两条都会失败,且 docker compose ps 显示 app 为 Exited。
Connection refused 表示 TCP 连接被拒绝,常见于进程未监听或端口错误;Operation timed out 表示连接或读取超时,通常返回 504。docker compose ps。app 为 Exited 时是进程未启动;app 为 Up 但目标端口拒绝连接时是端口写错。proxy_next_upstream 是否掩盖了部分失败。把 upstream 端口改回 80,重载 Nginx:
sed -i 's|http://app:8080|http://app:80|' /tmp/lab-nginx/edge.conf
docker compose -f /tmp/lab-nginx/docker-compose.yml exec -T edge nginx -s reload
sleep 2
curl -s -o /dev/null -w 'root_code=%{http_code}\n' http://127.0.0.1:8080/
root_code=200 表示恢复。生产环境还要检查 upstream 健康检查、连接池、超时参数和配置变更流程,避免单实例故障放大为 502。
docker compose -f /tmp/lab-nginx/docker-compose.yml down -v --remove-orphans
rm -rf /tmp/lab-nginx
只删除本实验的 Compose 项目和 /tmp/lab-nginx;不要对宿主机 Nginx 或 /etc/nginx 执行修改。
docker compose ps 判断进程状态;端口错误时进程在运行但目标端口不通。proxy_read_timeout 内没收到响应,属于网关超时,返回 504。