Docker环境下Node.js应用Fetch请求失败,本地运行正常
问题原因
Docker容器拥有独立的网络命名空间,容器内的127.0.0.1和localhost指向容器自身,而非你的Mac主机。你的Next.js服务运行在Mac主机的3000端口,容器内的应用请求127.0.0.1:3000时,实际是在访问容器内部的3000端口——这个端口没有运行任何服务,因此抛出连接拒绝错误。
解决方案
MacOS环境下,最简便的解决方式是使用Docker官方提供的特殊域名host.docker.internal,它会自动解析到宿主机(你的Mac)的IP地址。
修改请求地址
将Node.js应用中fetch的目标地址替换为host.docker.internal:
// 原代码中的请求地址 const rawResponse = await fetch( "http://127.0.0.1:3000/api/notifications/push", // ...其他配置 ); // 修改后 const rawResponse = await fetch( "http://host.docker.internal:3000/api/notifications/push", // ...其他配置 );
如果是复现案例中的测试请求,同样修改:
// 原测试地址 const rawResponse = await fetch("https://localhost:3000/api/test"); // 修改后(注意Next.js默认使用http,若未配置HTTPS请去掉s) const rawResponse = await fetch("http://host.docker.internal:3000/api/test");
重新构建并运行容器
修改完成后,重新构建镜像并启动容器:
docker build -t commerce-karma-notify . docker run commerce-karma-notify
其他可选方案
- 使用宿主机实际IP:通过
ifconfig(MacOS)命令查看你的局域网IP,替换127.0.0.1。但该IP会随网络环境变化,不如host.docker.internal稳定。 - 统一Docker网络部署:若Next.js服务也用Docker部署,可创建自定义网络,将两个容器加入同一网络,通过容器名称作为域名互相访问。这种方式适合多服务Docker化的场景。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

