使用docker-compose时浏览器出现net::ERR_NAME_NOT_RESOLVED错误求助
问题根源
浏览器发起的API请求是在用户本地主机环境执行的,而非client容器内部。Docker网桥网络的DNS解析(识别ecommerce-product这个容器名)只在容器之间生效,你的本地主机DNS根本不知道这个域名,所以会出现net::ERR_NAME_NOT_RESOLVED错误。而client容器内用curl能成功,是因为容器处于Docker网桥网络中,Docker自带的DNS服务可以解析同网络内的容器名。
解决方案
以下是几种可行的解决方式,按场景推荐:
1. 直接映射服务端端口到主机,修改客户端请求地址
步骤1:修改docker-compose.yml,给server添加端口映射
把server服务的expose补充端口映射配置,让服务端端口暴露到主机:
services: server: build: Ecommerce-products/ container_name: ecommerce-product networks: - ecommerce ports: # 新增端口映射,让主机能访问服务端 - "8080:8080" expose: - "8080"
步骤2:修改客户端API请求地址
把请求地址改成主机的localhost(或主机局域网IP)加映射的端口:
this.httpClient.get<any>("http://localhost:8080/products").subscribe(data => { this.products = data; });
注意:如果是在其他设备访问你的主机,要换成主机的局域网IP,比如
http://192.168.x.x:8080/products
2. 开发环境用Angular代理配置(推荐)
因为你用的是Angular的npm start开发服务器,可以配置代理转发,避免硬编码地址和跨域问题:
步骤1:在Angular项目根目录创建proxy.conf.json
{ "/products": { "target": "http://ecommerce-product:8080", "secure": false, "changeOrigin": true } }
步骤2:修改package.json的start命令,指定代理配置
{ "scripts": { "start": "ng serve --proxy-config proxy.conf.json" } }
步骤3:修改客户端API请求为相对路径
this.httpClient.get<any>("/products").subscribe(data => { this.products = data; });
这样Angular开发服务器会把/products的请求转发到容器内的服务端,同时浏览器的请求是发给本地的4200端口,不会出现DNS解析问题。
3. 生产环境用反向代理(Nginx)
如果是生产部署,可以用Nginx容器作为统一入口,把前端和后端的请求都通过Nginx转发,这样前端可以用相对路径请求:
修改docker-compose.yml,添加Nginx服务
services: client: build: Ecommerce-client/ container_name: ecommerce-client networks: - ecommerce # 不需要对外暴露端口,让Nginx转发 # ports: # - 4200:4200 server: build: Ecommerce-products/ container_name: ecommerce-product networks: - ecommerce expose: - "8080" nginx: image: nginx:alpine container_name: ecommerce-nginx ports: - "80:80" networks: - ecommerce volumes: - ./nginx.conf:/etc/nginx/nginx.conf # 挂载自定义配置 depends_on: - client - server
创建nginx.conf配置文件
events {} http { server { listen 80; # 转发前端请求到client容器 location / { proxy_pass http://ecommerce-client:4200; proxy_set_header Host $host; } # 转发API请求到server容器 location /products { proxy_pass http://ecommerce-product:8080; proxy_set_header Host $host; } } }
修改客户端API请求为相对路径
this.httpClient.get<any>("/products").subscribe(data => { this.products = data; });
用户访问主机的80端口时,Nginx会自动转发前端和API请求,既解决DNS问题,也避免跨域。
内容的提问来源于stack exchange,提问作者Samuele Pipitone
相关产品推荐
相关产品推荐

