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

Docker环境下多Angular应用Nginx反向代理403错误求助

Docker多Nginx容器部署Angular应用的403错误排查与解决思路

问题场景

在Docker环境中部署两个不同版本的Angular应用,搭配Nginx反向代理容器实现域名路由:

  • mobile-v1:基于AngularJS的旧版应用,监听8090端口
  • mobile-v2:新版Angular应用,监听8091端口
  • Nginx反向代理容器:通过80端口实现域名路由

容器间可正常ping通,直接curl应用容器端口返回200,但通过代理访问localhost时返回403 Forbidden错误。

环境配置

Docker Compose配置

services:
  mobile-v1:
    build:
      context: ../staging/cplan-v1-mobile-frontend
      dockerfile: ../../cplan-docker-compose/dockerfiles/staging/mobile-v1.Dockerfile
    container_name: mobile-v1
    ports:
      - "8090:8090"
    volumes:      
      - ./nginx/staging/front-services/cplan-mobile-v1.conf:/etc/nginx/conf.d/default.conf
      - ./logs/staging/nginx:/var/log/nginx
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    networks:
      - app-network
    restart: always

  mobile-v2:
    build:
      context: ../staging/cplan-v2-mobile-frontend
      dockerfile: ../../cplan-docker-compose/dockerfiles/staging/mobile-v2.Dockerfile
    container_name: mobile-v2
    ports:
      - "8091:8091"
    volumes:
      - ./nginx/staging/front-services/cplan-mobile-v2.conf:/etc/nginx/conf.d/default.conf
      - ./logs/staging/nginx:/var/log/nginx
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    networks:
      - app-network    
    restart: always

networks:
  app-network:
    driver: bridge

反向代理Nginx配置

server {
    listen 80;
    listen [::]:80;
    server_name mobile-v1.xxx.fr;

    location / {
        proxy_pass http://mobile-v1:8090;
        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;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name mobile-v2.xxx.fr;

    location / {
        proxy_pass http://mobile-v2:8091;
        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;
    }
}

mobile-v2的Nginx配置

server {
    listen 8091;
    listen [::]:8091;

    server_name mobile-v2;

    root /usr/share/nginx/html/mobile-v2;
    index index.html;

    access_log /var/log/nginx/access-mobile-v2.log;
    error_log /var/log/nginx/error-mobile-v2.log;

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

测试结果

  • 在代理容器内执行ping mobile-v2 → 成功
  • 在代理容器内执行curl -I http://mobile-v2:8091 → 返回200,成功
  • 在代理容器内执行curl -I http://localhost → 返回403,失败

解决思路

1. 修正代理请求的Host头匹配问题

当前代理配置仅匹配mobile-v1.xxx.fr和mobile-v2.xxx.fr的Host请求,访问localhost时没有对应的server块,Nginx触发默认行为返回403。

  • 测试验证:执行curl -I -H "Host: mobile-v2.xxx.fr" http://localhost,若返回200则说明配置逻辑正常,仅需在实际访问时携带正确的Host头(或配置本地DNS/hosts映射)。
  • 永久修正:添加默认server块,或修改现有server的server_name包含localhost,例如:
    server_name mobile-v2.xxx.fr localhost;
    

2. 调整应用容器的Nginx Host匹配

代理转发时设置了proxy_set_header Host $host,即请求Host为mobile-v2.xxx.fr,但mobile-v2的Nginx配置中server_name mobile-v2,两者不匹配可能导致路由异常。

  • 修改应用容器的Nginx配置,将server_name改为_(匹配任意Host):
    server_name _;
    

3. 验证代理容器的Nginx配置有效性

进入代理容器,执行以下命令确保配置合法且生效:

nginx -t  # 检查配置语法
nginx -s reload  # 重载配置

4. 检查应用容器的文件权限

确保Nginx进程有权限读取应用静态文件:
进入mobile-v2容器执行:

ls -l /usr/share/nginx/html/mobile-v2
# 若权限异常,执行
chown -R nginx:nginx /usr/share/nginx/html/mobile-v2

5. 优化容器端口配置(可选)

应用容器的端口映射(8090、8091)仅用于宿主机直接访问,容器间通信依赖Docker网络,可去掉应用容器的ports配置,仅保留代理容器的80端口映射,减少不必要的端口暴露。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:15:15