群晖NAS上NGINX、NodeJS(Docker)跨域问题求助
解决群晖NAS上Docker部署的前后端跨域问题
问题根源
当通过自定义DNS访问前端时,前端代码中硬编码的http://localhost:3000会被客户端浏览器解析为用户本地机器的3000端口,而非NAS上的后端容器。同时,自定义DNS域名与localhost属于不同源,浏览器的同源策略会阻止跨域请求,导致CORS错误。此外,当前配置没有利用Docker容器间的内部网络通信,而是直接暴露后端端口到外部,这既不安全也加剧了跨域问题。
解决方案
1. 配置Nginx反向代理API请求
更新nginx.conf,添加反向代理规则,将前端的API请求转发到后端容器。这样前端可以通过相对路径请求API,避免跨域:
events {} http { include /etc/nginx/mime.types; server { listen 80; server_name localhost your-custom-dns.example.com; root /frontend/dist/browser; index index.html; # 转发API请求到后端容器 location /api/ { proxy_pass http://backend: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; } location / { try_files $uri $uri/ /index.html; } location ~* \.(js|css)$ { expires 1y; add_header Cache-Control public; } } }
2. 调整前端API基础地址
修改Angular前端的API配置,将硬编码的http://localhost:3000改为相对路径/api,确保请求发送到当前域名:
// src/environments/environment.prod.ts export const environment = { production: true, apiBaseUrl: '/api' };
3. 优化Docker Compose网络配置(可选)
Docker Compose默认会为所有服务创建共享网络,但明确指定自定义网络可提升配置可读性,同时可关闭后端的端口映射(若无需直接外部访问后端):
version: '3.8' networks: app-network: driver: bridge services: frontend: container_name: frontend build: context: ./ cache_from: - frontend dockerfile: ./apps/projects/frontend/Dockerfile image: frontend ports: - 4200:80 environment: NODE_ENV: 'production' restart: on-failure networks: - app-network postgres: container_name: postgres image: postgres:latest environment: POSTGRES_USER: foo POSTGRES_PASSWORD: bar PG_DATA: /var/lib/postgresql/data ports: - 1234:5432 volumes: - pgdata:/var/lib/postgresql/data networks: - app-network backend: depends_on: - postgres container_name: backend build: context: ./ cache_from: - backend dockerfile: ./apps/projects/backend/Dockerfile image: backend # 若无需直接外部访问后端,可注释端口映射 # ports: # - 3000:3000 restart: on-failure networks: - app-network volumes: pgdata: {}
4. 重新部署服务
在NAS上执行以下命令重新构建并启动容器:
docker-compose down docker-compose up --build -d
核心原理
- Docker内部网络:通过服务名
backend直接访问后端容器,利用Docker的内部DNS解析,无需暴露端口到NAS主机,避免了跨域和外部直接访问的安全风险。 - Nginx反向代理:将前端的API请求转发到后端容器,前端请求的是当前域名的路径,符合浏览器同源策略,彻底解决CORS问题。
内容的提问来源于stack exchange,提问作者Florestan Korp
相关产品推荐
相关产品推荐

