Next.js构建Docker镜像时生成静态页面报本地连接被拒错误
问题根因
连接被拒是两个配置认知偏差导致的:
- Windows环境下Docker Desktop基于WSL2轻量虚拟化实现,你配置的
build.network: "host"仅在Linux原生Docker环境生效,构建阶段临时容器里的127.0.0.1指向容器本身,而非运行CMS的Windows宿主机。另外你配的network_mode: "host"只对容器运行阶段生效,完全不影响构建阶段的网络栈。 - 本地默认启动的无头CMS通常仅绑定
127.0.0.1回环地址,就算容器能定位到宿主机IP,也会被监听规则拦截无法访问。
可直接落地的修复步骤
- 调整无头CMS监听配置
把CMS的启动监听地址从127.0.0.1改成0.0.0.0,允许来自非回环地址的请求访问7071端口。如果弹出Windows防火墙安全提示,勾选允许专用网络下的入站连接即可。 - 替换硬编码的本地CMS地址
不要在getStaticProps里硬编码http://localhost:7071,改成读取环境变量的形式,方便构建阶段注入正确的访问地址。 - 调整docker-compose构建配置
Docker Desktop在Windows/macOS下内置了特殊域名host.docker.internal,会自动解析到宿主机的可访问IP,直接用这个域名替代localhost即可。修改后的docker-compose.yml参考如下:
services: web: build: dockerfile: Dockerfile context: . args: - CMS_API=http://host.docker.internal:7071 network_mode: "host" environment: - CMS_API=http://localhost:7071
- 修改Dockerfile接收构建参数
在builder阶段开头加参数声明,保证npm run build:local执行时能读到正确的CMS地址:
FROM node:18-alpine as builder # 新增参数声明 ARG CMS_API ENV NEXT_PUBLIC_CMS_API=$CMS_API WORKDIR /app # 原有其余配置保持不变
把代码里原来写死的http://localhost:7071替换成process.env.NEXT_PUBLIC_CMS_API即可。
更稳定的备选方案
如果不想折腾宿主机网络配置,可以直接把本地的无头CMS也加入到同一个docker-compose.yml的服务列表里,两个服务同属一个Docker内部网络,构建阶段直接用CMS的服务名作为访问地址即可,完全不依赖宿主机网络和防火墙配置,环境一致性更高。
内容的提问来源于stack exchange,提问作者Nicholas Barfknecht
相关产品推荐
相关产品推荐

