Docker部署.NET后端+Angular前端应用时出现net::ERR_NAME_NOT_RESOLVED错误求助
Docker部署.NET后端+Angular前端应用时出现net::ERR_NAME_NOT_RESOLVED错误求助
看起来你遇到的问题挺典型的——前端容器内部能正常curl通后端服务,但浏览器里的前端应用却报域名解析失败对吧?这本质上是Docker内部网络和浏览器请求上下文不匹配导致的,我来帮你拆解问题并给出解决方案:
问题根源分析
你在前端容器里用curl能访问http://backend:80,是因为所有容器都在Docker Compose创建的app_internal_network内部网络中,Docker自带的DNS服务会把backend这个服务名解析成对应容器的IP地址。
但浏览器的API请求是从你的本地机器发起的,它只会使用本地的DNS系统去解析地址,根本不知道Docker内部的backend服务名是什么,自然就会抛出ERR_NAME_NOT_RESOLVED错误。
另外看你的配置,还有几个明显的错误点:
nginx.conf里的server_name http://backend:80完全错误,server_name是用来定义当前Nginx服务的域名标识,不是后端服务的地址- 你的Angular应用的API请求地址应该是硬编码/配置成了
http://backend:80/xxx,这个地址在浏览器环境下完全不可用 nginx.conf里的CORS配置混乱(同时设置了通配符和特定Origin),而且如果用反向代理的话,CORS配置其实是多余的
解决方案(推荐用Nginx反向代理)
用Nginx作为前端静态文件服务器的同时,反向代理所有API请求到后端服务,这样既解决了域名解析问题,又避免了跨域问题,是生产环境的标准做法。
1. 修正Nginx配置(nginx.conf)
替换成以下配置,重点是添加反向代理的location块,同时清理错误的配置:
worker_processes 1; events { worker_connections 1024; } http { server { listen 80; server_name localhost; # 定义当前Nginx服务的标识,容器内可留空或设为localhost root /usr/share/nginx/html/browser; index index.html index.htm; include /etc/nginx/mime.types; # Gzip压缩配置保留,没问题 gzip on; gzip_http_version 1.1; gzip_disable "MSIE [1-6]\."; gzip_min_length 256; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_comp_level 9; # 处理SPA路由,确保刷新页面不会404 location / { try_files $uri $uri/ /index.html; } # 反向代理所有API请求到后端服务 location /api/ { proxy_pass http://backend:80/; # Docker内部网络可直接解析backend服务名 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } }
2. 修改Angular应用的API地址配置
打开你的Angular项目的src/environments/environment.prod.ts,把API基础地址改成当前域名的/api路径:
export const environment = { production: true, apiBaseUrl: '/api' // 所有API请求都会发向这个路径,由Nginx转发到后端 };
重新构建前端应用,然后重新构建前端Docker镜像。
3. 确认Docker Compose配置
你的Docker Compose配置基本没问题,注意:
- 前端服务的
ports: - 80:80是对的,用户访问http://localhost就能打开前端 - 后端服务的
ports: - 8080:80可以保留,但生产环境建议不要暴露后端端口,完全通过Nginx反向代理访问
备选测试方案(仅用于临时验证)
如果只是想快速验证后端接口,不想改Nginx配置,可以:
- 确保后端服务的端口映射
8080:80正常 - 修改Angular的
environment.prod.ts里的API地址为http://localhost:8080 - 后端服务配置CORS允许
http://localhost的请求(因为此时前端在http://localhost,后端在http://localhost:8080,属于跨域)
但这个方案不适合生产环境,因为会直接暴露后端服务,且存在跨域安全风险。
备注:内容来源于stack exchange,提问作者Şahin Yakıcı
相关产品推荐
相关产品推荐

