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

如何通过Docker-Compose配置Nginx反向代理EC2上的前后端容器?

解决Nginx反向代理多容器的配置问题

嘿,我看了你的配置,发现几个关键问题导致Nginx没法正确区分前端和后端请求,下面给你一步步梳理解决方案:

首先,你的Nginx配置里有个致命问题:两个完全相同的location /块。Nginx在匹配请求路径时,会优先执行第一个符合条件的规则,所以所有请求都会被转发到前端容器,后端的配置根本不会生效。另外,Docker Compose里没必要把前端和后端的端口暴露到主机(ports字段)——同一Docker网络里的容器可以直接通过服务名互相访问,暴露端口反而增加了不必要的安全风险。

下面是调整后的完整配置方案:

1. 修改Nginx配置文件 (./conf/nginx.conf)

我们给后端请求设置一个专属的路径前缀(比如/api),让Nginx能明确区分前端页面请求和后端API请求:

events {
    worker_connections 4096;
}
http {
    # 开启gzip压缩,优化传输性能
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    server {
        listen 80;
        listen [::]:80;
        server_name myDomainName.com;

        # 前端页面请求:所有非/api开头的路径都转发到前端容器
        location / {
            proxy_pass http://frontend:3000/;
            # 传递请求头,让前端能正确识别主机信息
            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;
        }

        # 后端API请求:所有/api开头的路径转发到后端容器
        location /api/ {
            proxy_pass http://backend:8400/;
            # 传递请求头,后端可以获取客户端真实IP等信息
            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_pass_request_headers on;
        }
    }
}

2. 优化Docker Compose配置

去掉前端和后端的ports字段(不需要暴露到主机),同时给Nginx加上启动依赖,确保前端后端先启动:

version: "3"
services:
  nginx:
    container_name: nginx
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./conf/nginx.conf:/etc/nginx/nginx.conf
    # 让Nginx在前端、后端启动后再启动,避免服务找不到的问题
    depends_on:
      - frontend
      - backend
  frontend:
    container_name: frontend
    image: myfrontend:image
    # 移除ports,容器内访问不需要暴露到主机
  backend:
    container_name: backend
    depends_on:
      - db
    environment:
      DB_HOST: db
    image: mybackend:image
    # 移除ports,容器内访问不需要暴露到主机
  db:
    container_name: mongodb
    environment:
      MONGO_INITDB_DATABASE: myDB
    image: mongo:latest
    # 如果不需要外部直接连接数据库,可以把这行也去掉
    ports:
      - "27017:27017"
    volumes:
      - ./initialization/db:/docker-entrypoint-initdb.d
      - db-volume:/data/db
volumes:
  db-volume:

关键注意点

  • 路径区分:前端需要把所有API请求都发到/api前缀下(比如用fetch('/api/get-data')),这样Nginx会自动转发到后端容器。
  • 容器网络:Docker Compose默认会给所有服务创建一个共享网络,容器之间可以直接通过服务名(frontend、backend、db)访问,不用依赖主机IP。
  • 请求头传递:proxy_set_header的配置能让后端获取到客户端的真实IP和请求协议,避免部分业务逻辑出错。

验证配置

修改完后重启容器即可生效:

docker-compose down && docker-compose up -d

访问http://myDomainName.com应该能看到前端页面,访问http://myDomainName.com/api/xxx就能获取后端API的响应了。

内容的提问来源于stack exchange,提问作者ECL-94

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:27:45