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
相关产品推荐
相关产品推荐

