跨Nginx容器无法访问webhost1心跳接口问题求助
问题描述
我运行了带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; } // 原有业务逻辑
额外检查点
- 查看webhost1的Nginx错误日志,确认具体错误:
docker exec webhost1 cat /var/log/nginx/error.log
- 确认webhost1的PHP-FPM是否正常运行:
docker exec webhost1 ps aux | grep php-fpm
内容的提问来源于stack exchange,提问作者Ravi kant Gautam

