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

前端容器通过API访问后端容器出现502错误的排查求助

问题描述

在Docker环境中部署了前端(Vue开发服务器,暴露5173端口)、后端(PHP-FPM,暴露9000端口)及Nginx服务,已配置docker-compose.yml、backend.conf和frontend.conf文件,且hosts文件中已配置.env变量对应的URL。前端页面可正常显示,但在前端index.html中通过XMLHttpRequest发送/api/test请求至后端时,返回502错误,需排查解决。

相关配置

docker-compose.yml

services:
  # PHP Application
  backend:
    build:
      context: .
      dockerfile: docker/backend/Dockerfile
      args:
        APP_ENV: ${APP_ENV:-development}
    container_name: ${APP_NAME}-backend
    restart: unless-stopped
    volumes:
      - ./backend:/var/www/backend
    networks:
      - app
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - "9000:9000"

  frontend:
    build:
      context: .
      dockerfile: docker/frontend/Dockerfile
    working_dir: /app
    container_name: ${APP_NAME}-frontend
    restart: unless-stopped
    tty: true
    volumes:
      - ./frontend:/app
    networks:
      - app
    ports:
      - "${NGINX_FRONTEND_PORT:-5173}:5173" # Vue dev server

  # Web Server
  webserver:
    build:
      context: .
      dockerfile: docker/nginx/Dockerfile
    environment:
      BACKEND_URL: ${BACKEND_URL}
      FRONTEND_URL: ${FRONTEND_URL}
      FRONTEND_DEV_URL: ${FRONTEND_DEV_URL}
    container_name: ${APP_NAME}-webserver
    restart: unless-stopped
    ports:
      - "${NGINX_HTTP_PORT:-80}:80"
      - "${NGINX_HTTPS_PORT:-443}:443"
    volumes:
      - ./backend:/var/www/backend:delegated
      - ./frontend:/var/www/frontend:delegated
      - ./docker/nginx/logs:/var/log/nginx
      - ./docker/nginx/ssl:/etc/nginx/ssl:ro
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - app
    depends_on:
      - backend
      - frontend

networks:
  app:
    driver: bridge

backend.conf

server {
    listen 80;
    server_name ${BACKEND_URL};

    root /var/www/backend/public;
    index index.php;

    # 日志
    access_log /var/log/nginx/backend_access.log;
    error_log /var/log/nginx/backend_error.log;

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

    # 处理.php文件
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass backend:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }

    location ~ /\.ht {
        deny all;
    }
}

frontend.conf

server {
    listen 80;
    server_name ${FRONTEND_URL};

    root /var/www/frontend/dist;
    index index.html;

    # 日志
    access_log /var/log/nginx/frontend_access.log;
    error_log /var/log/nginx/frontend_error.log;

    add_header Access-Control-Allow-Origin $http_origin;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://backend:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen 80;
    server_name ${FRONTEND_DEV_URL};

    root /var/www/frontend;
    index index.html;

    # 日志
    access_log /var/log/nginx/frontend_dev_access.log;
    error_log /var/log/nginx/frontend_dev_error.log;

    add_header Access-Control-Allow-Origin $http_origin;

    location / {
        proxy_pass http://frontend:5173;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /api/ {
        proxy_pass http://backend:9000;
        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;
        proxy_set_header Authorization $http_authorization;
        # proxy_set_header Upgrade $http_upgrade;
        # proxy_set_header Connection "upgrade";
    }
}

后端Dockerfile关键配置

EXPOSE 9000
CMD ["php-fpm"]

前端Dockerfile关键配置

EXPOSE 5173
CMD ["npm", "run", "dev"]

前端请求代码

let xhr = new XMLHttpRequest();

xhr.open('GET', '/api/test');

xhr.send();

xhr.onload = function() {
    console.log(xhr.response)
    if (xhr.status != 200) { 
        console.log(`Error ${xhr.status}: ${xhr.statusText}`);
    } else {
        console.log(`Success, got ${xhr.response.length} 字节`);
    }
};

xhr.onprogress = function(event) {
    if (event.lengthComputable) {
        console.log(`已接收 ${event.loaded} / ${event.total} 字节`);
    } else {
        console.log(`已接收 ${event.loaded} 字节`);
    }

};

xhr.onerror = function() {
    console.log("请求失败");
};

排查与解决方案

502错误核心原因是Nginx错误地用HTTP代理方式转发请求到PHP-FPM的FastCGI端口,PHP-FPM不支持HTTP协议,需改用FastCGI转发规则。

1. 修正frontend.conf中的/api转发配置

找到FRONTEND_DEV_URL对应的server块,替换/api/的location配置为FastCGI转发:

location /api/ {
    root /var/www/backend/public;
    try_files $uri $uri/ /index.php?$query_string;

    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass backend:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param Host $host;
    fastcgi_param X-Real-IP $remote_addr;
    fastcgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
    fastcgi_param X-Forwarded-Proto $scheme;
    fastcgi_param Authorization $http_authorization;
}

同时,FRONTEND_URL对应的server块中的/api/配置也需要做同样修改,避免生产环境出现相同问题。

2. 验证后端服务连通性

进入Nginx容器,测试能否连接到backend容器的9000端口:

# 替换为你的webserver容器名称
docker exec -it ${APP_NAME}-webserver ping backend
# 测试端口连通
docker exec -it ${APP_NAME}-webserver telnet backend 9000

如果连接失败,检查所有服务是否都加入了app网络,确保docker-compose的network配置正确。

3. 查看Nginx错误日志定位细节

查看日志获取具体报错信息:

# 前端dev环境错误日志
cat ./docker/nginx/logs/frontend_dev_error.log
# 后端错误日志
cat ./docker/nginx/logs/backend_error.log

日志会明确提示是连接拒绝、超时还是FastCGI配置错误,帮助快速定位问题。

4. 确认后端配置与权限

  • 确保后端/var/www/backend/public/index.php文件存在,且Nginx容器对该路径有读取权限;
  • 检查PHP-FPM配置(通常是www.conf),确认监听地址为0.0.0.0:9000,而非仅本地127.0.0.1,否则容器外无法访问。

5. 验证后端路由

确认后端代码中存在/api/test对应的路由,且能正常处理GET请求。


内容的提问来源于stack exchange,提问作者mepihindeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:59:49