Docker容器中Next.js应用无法解析auth-service域名的问题
问题分析与解决方案
核心原因
Docker Compose创建的内部网络中,服务名(如auth-service)仅能被同一Docker网络内的容器解析。但你的Next.js前端代码是在浏览器中运行的,浏览器属于宿主机网络环境,完全无法识别Docker内部的DNS规则,因此会出现ERR_NAME_NOT_RESOLVED错误。
解决方案
方案1:端口映射+宿主机地址(快速测试用)
给auth-service添加端口映射,让宿主机能直接访问它,前端配置改用宿主机地址:
- 修改Docker Compose文件,给
auth-service添加ports配置:auth-service: build: context: ./penai-backend/auth-service dockerfile: Dockerfile-auth-service depends_on: - auth-db container_name: auth-service ports: - "8080:8080" # 宿主机端口8080映射到容器内8080 - 更新
.env.local文件:NEXT_PUBLIC_AUTH_SERVICE_DOMAIN=localhost NEXT_PUBLIC_AUTH_SERVICE_PORT=8080 - 重启Docker Compose服务,前端即可通过
localhost:8080访问auth-service。
方案2:反向代理(生产环境推荐)
利用Next.js的反向代理功能,让运行在Docker容器内的前端服务器(属于Docker网络)转发请求到auth-service,浏览器只需请求前端服务的路径即可:
- 在Next.js项目根目录创建/修改
next.config.js:module.exports = { async rewrites() { return [ { source: '/api/auth/:path*', destination: 'http://auth-service:8080/:path*', }, ]; }, }; - 修改
getServiceURL.js,返回相对路径:const servicesConfig = require("../../services.config"); export function getServiceURL(serviceName) { if (serviceName === "authService") { return '/api/auth'; } // 其他服务的逻辑保持不变 const service = servicesConfig[serviceName]; if (!service) throw new Error(`Service '${serviceName}' not found in the configuration.`); return `http://${service.domain}:${service.port}`; } - 重启前端容器,此时浏览器请求
/api/auth/xxx时,会由Next.js服务器转发到Docker内部的auth-service:8080/xxx,既解决了DNS解析问题,又避免了直接暴露后端服务端口。
方案3:自定义DNS(不推荐)
手动配置宿主机的DNS解析,将auth-service指向容器的IP,但容器IP重启后会变化,需要额外维护,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者Anıl Eren Göçer
相关产品推荐
相关产品推荐

