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

EC2上Docker Compose+Nginx部署:前端无法访问后端(502错误)

问题:Docker Compose部署后Nginx反向代理/api接口返回502错误

部署环境

在EC2实例上通过Docker Compose部署三类服务:

  • account-generator:FastAPI应用
  • money-tracker:分为Golang后端与React前端
  • Nginx:作为反向代理管理域名请求

Docker Compose配置

version: '3.9'

services:
  backend:
    container_name: myexample-backend
    build:
      context: backend
    command: ["air", "migrate", "&&", "air", "serve"]
    env_file:
      - backend/.env
    ports:
      - "18001:18001"
    volumes:
      - ./certbot/conf/:/etc/nginx/ssl/
    networks:
      myexample-webserver-network: {}

  frontend:
    container_name: myexample-frontend
    build:
      context: frontend
      dockerfile: Dockerfile
    env_file:
      - frontend/.env-prod
    command: ["npm", "run", "start:prod"]
    ports:
      - "13001:3000"
    networks:
      myexample-webserver-network: {}
    stdin_open: true

  account-generator:
    build:
      context: myexample-account-generator
    command: [ "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "18010" ]
    env_file:
      - .env
    ports:
      - "18010:18010"
    networks:
      myexample-webserver-network: { }

  webserver:
    container_name: myexample-nginx-production
    image: nginx
    volumes:
      - ./nginx/conf/production.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - backend
      - frontend
      - myexampleapp
    networks:
      myexample-webserver-network: {}

networks:
  myexample-webserver-network:
    external: true

Nginx配置

server {
    listen 80;
    listen [::]:80;
    root /var/www/html;
    server_name myexampledomain.com www.myexampledomain.com;
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://myexampledomain.com$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    root /var/www/html;
    server_name myexampledomain.com www.myexampledomain.com;

    keepalive_timeout 65;
    proxy_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;

    ssl_certificate /etc/nginx/ssl/live/myexampledomain.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/myexampledomain.com/privkey.pem;

    location / {
        proxy_pass http://money-tracker:18010;
    }
}

server {
    listen 80;
    listen [::]:80;
    root /var/www/html;
    server_name money-tracker.myexampledomain.com www.money-tracker.myexampledomain.com;
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://money-tracker.myexampledomain.com$request_uri;
    }

    location /api {
        return 301 https://money-tracker.myexampledomain.com/api$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    root /var/www/html;
    server_name localhost money-tracker.myexampledomain.com www.money-tracker.myexampledomain.com;

    keepalive_timeout 65;
    proxy_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;

    ssl_certificate /etc/nginx/ssl/live/money-tracker.myexampledomain.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/money-tracker.myexampledomain.com/privkey.pem;

    location / {
        proxy_pass http://frontend:3000;
    }

    location /api {
        chunked_transfer_encoding off;
        proxy_pass http://backend:18001;
    }
}

当前问题

已完成域名购买及Route 53 DNS配置,预期:

  • 主域名myexampledomain.com运行account-generator
  • 子域名money-tracker.myexampledomain.com运行money-tracker

实际状态:

  • 主域名、子域名前端访问正常
  • 外部请求(前端调用子域名/api接口、Postman/Insomnia请求)均返回502错误
  • SSH到EC2实例后,curl后端服务可正常接收请求

已尝试修改Docker Compose配置、Nginx配置、EC2的/etc/hosts,问题未解决


排查与修复方案

1. 修正Docker Compose配置错误

  • 修复webserver的依赖服务名:原配置中webserver的depends_on包含不存在的myexampleapp,替换为实际服务名account-generator:
depends_on:
  - backend
  - frontend
  - account-generator
  • 给account-generator添加容器名:明确容器名避免网络解析歧义:
account-generator:
  container_name: account-generator
  # 其余配置不变
  • 给Nginx添加certbot目录挂载:原Nginx配置引用了/var/www/certbot但未挂载,添加后保证ACME挑战路径有效:
webserver:
  volumes:
    - ./nginx/conf/production.conf:/etc/nginx/conf.d/default.conf
    - ./certbot/www:/var/www/certbot  # 新增此挂载

2. 修正Nginx配置错误

  • 主域名反向代理目标修正:原配置主域名指向money-tracker:18010,改为account-generator:18010符合预期:
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    # 其余配置不变
    location / {
        proxy_pass http://account-generator:18010;
    }
}
  • 删除子域名80端口冗余的/api规则:该规则会导致重复跳转,直接删除:
# 删掉以下内容
location /api {
    return 301 https://money-tracker.myexampledomain.com/api$request_uri;
}
  • 给/api反向代理添加必要请求头:后端服务可能需要正确的客户端信息才能处理请求,在location /api块中添加:
location /api {
    chunked_transfer_encoding off;
    proxy_pass http://backend:18001;
    # 新增以下请求头配置
    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;
}

3. 验证Docker网络连通性

进入Nginx容器,测试能否直接访问backend服务:

docker exec -it myexample-nginx-production curl http://backend:18001/api/health

如果无法访问,检查网络成员:

docker network inspect myexample-webserver-network

确保backend、frontend、account-generator、webserver四个服务都在该网络中

4. 确认后端监听地址

检查Golang后端服务的启动命令,确保监听地址是0.0.0.0:18001,而非127.0.0.1:18001(后者仅容器内部可访问)


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:18:09