Docker+Nginx环境下Laravel API无法访问(502错误)求助
我正在开发一个以Laravel为后端API、NextJS为独立前端的应用,采用Docker与Nginx部署。目前Nginx配置完成后可正常访问前端UI,但请求Laravel API端点时出现502 Bad Gateway错误。以下是相关配置及错误信息:
Docker-compose配置
services: ###### FRONTEND SERVICES ## Node容器(运行NextJS前端项目) findra-node: build: context: ./docker/node container_name: findra-node restart: unless-stopped volumes: - type: bind source: ./federer target: /var/www/finaldraw/federer working_dir: /var/www/finaldraw/federer command: ["npm", "run", "dev"] healthcheck: test: ["CMD", "curl", "-f", "finaldraw.local:3000"] interval: 15s timeout: 5s retries: 150 networks: - frontend ###### BACKEND SERVICES ## Nginx容器 findra-nginx: container_name: findra-nginx build: context: ./docker/nginx dockerfile: Dockerfile restart: unless-stopped depends_on: findra-php: condition: service_healthy findra-node: condition: service_healthy ports: - protocol: tcp published: ${NGINX_PORT} target: 80 healthcheck: test: ["CMD", "curl", "-k", "-f", "finaldraw.local:80"] interval: 15s timeout: 5s retries: 150 networks: - frontend - backend ## PHP容器(运行Laravel后端) findra-php: container_name: findra-php build: context: ./docker/php args: USER_ID: ${USER_ID:-0} GROUP_ID: ${GROUP_ID:-0} user: www-data:www-data restart: unless-stopped volumes: - type: bind source: ./nadal target: /var/www/finaldraw/nadal working_dir: /var/www/finaldraw/nadal healthcheck: test: ["CMD", "php-fpm-healthcheck"] interval: 15s timeout: 5s retries: 150 networks: - backend
Nginx配置
upstream federer { server findra-node:3000; } upstream nadal { server findra-php:9000; } server { listen 80; listen [::]:80; server_name mysite.local; charset utf-8; location / { proxy_pass http://federer/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /api/ { proxy_pass http://nadal/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
PHP Dockerfile已暴露9000端口,Node Dockerfile已暴露3000端口。访问前端http://mysite.local/正常,但请求API http://finaldraw.local/api/时返回:
<html> <head> <title>502 Bad Gateway</title> </head> <body> <center> <h1>502 Bad Gateway</h1> </center> <hr> <center>nginx/1.27.0</center> </body> </html>
1. 修正Nginx对PHP-FPM的协议适配
PHP-FPM使用FastCGI协议,而非HTTP,不能用proxy_pass转发请求。修改Nginx的/api/配置块为FastCGI模式:
location /api/ { root /var/www/finaldraw/nadal/public; try_files $uri $uri/ /index.php$is_args$args; fastcgi_pass http://nadal; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
2. 统一域名访问
前端使用mysite.local,API请求用finaldraw.local,需确保两个域名都指向Nginx容器的IP(修改本地/etc/hosts或DNS记录),或统一使用同一个域名避免跨域与解析问题。
3. 验证容器网络连通性
进入Nginx容器,测试能否连接到PHP-FPM容器:
# 测试ping连通性 docker exec -it findra-nginx ping findra-php # 测试端口连通性 docker exec -it findra-nginx telnet findra-php 9000
若无法连通,检查Docker网络配置:执行docker network inspect backend确认findra-nginx和findra-php均加入backend网络。
4. 确认PHP-FPM监听配置
进入PHP容器,检查PHP-FPM是否正常监听9000端口:
docker exec -it findra-php netstat -tulpn | grep 9000
若未监听,修改PHP-FPM配置文件(通常在/usr/local/etc/php-fpm.d/www.conf),确保listen = 0.0.0.0:9000(允许容器外部访问),而非listen = 127.0.0.1:9000(仅本地访问)。
5. 修复Laravel目录权限
确保PHP容器内的Laravel目录权限正确,www-data用户拥有读写权限:
docker exec -it findra-php chown -R www-data:www-data /var/www/finaldraw/nadal docker exec -it findra-php chmod -R 755 /var/www/finaldraw/nadal/storage /var/www/finaldraw/nadal/bootstrap/cache
内容的提问来源于stack exchange,提问作者Juan Pablo B

