You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨Nginx容器无法访问webhost1心跳接口问题求助

问题排查:Nginx反向代理返回502 Bad Gateway无法访问心跳接口

问题描述

我运行了带PHP扩展的Nginx容器webhost1,提供心跳服务(返回1-1000随机值,示例:heartbeat=34),运行正常,可通过curl http://localhost:8084获取心跳。

另运行暴露8080端口的Nginx容器ngx,其nginx.conf配置了proxy_pass http://webhost1:8084;,默认location如下:

location / {
    return 200 'Welcome to GW01 Reverse Proxy';
    add_header Content-Type text/plain;
}

通过curl http://localhost:8080可得到正确结果,且docker exec ngx curl http://webhost1:8084也能获取心跳,但执行curl http://localhost:8080/heartbeat时返回502 Bad Gateway,详细请求日志:

curl -v localhost:8080/heartbeat

* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /heartbeat HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 502 Bad Gateway
< Server: nginx/1.27.5
< Date: Fri, 30 May 2025 16:56:37 GMT
< Content-Type: text/html
< Content-Length: 157
< Connection: keep-alive
< 
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.27.5</center>
</body>
</html>
* Connection #0 to host localhost left intact

执行docker exec gw01 nginx -t测试配置显示语法正确:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

相关配置文件

ngx容器nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    
    sendfile on;
    keepalive_timeout 65;
    
    server {
        listen 80;
        server_name _;
        
        location /heartbeat {
#     proxy_pass http://10.10.5.6:8084;
      proxy_pass http://webhost1:8084;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
         }
        
        # Default location
        location / {
            return 200 'Welcome to GW01 Reverse Proxy';
            add_header Content-Type text/plain;
        }
    }
}

webhost1容器nginx.conf

worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen 8084;
        server_name localhost;

        root /var/www/html;

        location / {
            index index.php;
        }

        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
        }
    }
}

webhost1容器Dockerfile

FROM alpine

# Install NGINX and PHP-FPM
RUN apk add --no-cache \
    nginx \
    php82 \
    php82-fpm \
    php82-opcache \
    php82-mbstring \
    php82-session \
    php82-json

# Symlink php-fpm for simplicity
RUN ln -s /usr/sbin/php-fpm82 /usr/bin/php-fpm

# Create required dirs
RUN mkdir -p /run/nginx /var/www/html

# Copy config and content
COPY nginx.conf /etc/nginx/nginx.conf
COPY index.php /var/www/html/index.php

# Expose port
EXPOSE 8084

# Start PHP-FPM and NGINX
CMD ["sh", "-c", "php-fpm & nginx -g 'daemon off;'"]
问题原因及解决方案

核心问题

当请求http://localhost:8080/heartbeat时,ngx容器的Nginx会将请求代理到http://webhost1:8084/heartbeat,但webhost1的Nginx配置中,只有.php结尾的请求才会转发给PHP-FPM处理,/heartbeat路径既不匹配PHP规则,也没有对应的文件/目录,导致webhost1返回404,进而ngx容器返回502 Bad Gateway。

另外,proxy_set_header Host $host;设置的Host为localhost:8080,虽然能匹配webhost1的server_name localhost;,但不是核心问题。

修复步骤

方案1:修改ngx容器的proxy_pass路径

将ngx容器中location /heartbeat的proxy_pass修改为:

proxy_pass http://webhost1:8084/index.php;

直接将请求转发到webhost1的PHP入口文件,由PHP处理心跳逻辑。

方案2:在webhost1的Nginx中添加/heartbeat匹配规则

在webhost1的nginx.conf的server块中新增:

location /heartbeat {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME  /var/www/html/index.php;
}

让/heartbeat请求直接转发给PHP-FPM,复用现有的index.php文件。

方案3:修改webhost1的PHP路由逻辑

如果PHP代码支持路由,可在index.php中处理/heartbeat请求,同时修改webhost1的Nginx配置,将所有请求转发到index.php:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

然后在index.php中添加路由判断:

if ($_SERVER['REQUEST_URI'] === '/heartbeat') {
    echo 'heartbeat=' . rand(1, 1000);
    exit;
}
// 原有业务逻辑

额外检查点

  1. 查看webhost1的Nginx错误日志,确认具体错误:
docker exec webhost1 cat /var/log/nginx/error.log
  1. 确认webhost1的PHP-FPM是否正常运行:
docker exec webhost1 ps aux | grep php-fpm

内容的提问来源于stack exchange,提问作者Ravi kant Gautam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:17:03