Next.js Docker构建时无法连接后端API的问题求助
问题描述
我将Next.js+Nest.js+Nginx+PostgreSQL整合到一个docker-compose.yaml中部署,由于Next.js构建时需要调用可用的API,把启动流程分为三个阶段:
- 先启动后端和数据库:
docker-compose up backend database -d --build - 填充数据库:
docker-compose exec backend bun prisma db push、docker-compose exec backend bun seed - 最后启动前端和Nginx:
docker-compose up frontend nginx -d --build
在启动前端前,已确认http://localhost:4200/api响应正常,但前端镜像始终构建失败。试过指定localhost、127.0.0.1、backend、backend-test等域名,也加过--network=host参数,均无法解决。执行make back && make db && make front时,前端构建环节崩溃。
我的docker-compose配置如下:
services: backend: build: context: ./backend env_file: - path: ./backend/.env.production ports: - 4200:4200 depends_on: - database database: image: postgres:alpine ports: - 5432:5432 env_file: - ./backend/.env.production volumes: - postgres_data:/var/lib/postgresql/data frontend: # image: ${FRONTEND_IMAGE} build: context: ./frontend ports: - '3000:3000' volumes: - frontend-node-modules:/app/node_modules restart: always env_file: - ./frontend/.env.production depends_on: - backend nginx: build: context: ./.nginx/ restart: unless-stopped ports: - 80:80 - 443:443 volumes: - ./.nginx/nginx.conf:/etc/nginx/nginx.conf - ./.nginx/letsencrypt/:/etc/letsencrypt/ depends_on: - frontend - backend volumes: postgres_data: frontend-node-modules:
构建时的错误信息:
=> ERROR [frontend builder 6/6] RUN bun run build 18.7s ------ > [frontend builder 6/6] RUN bun run build: 0.330 $ NODE_ENV=production next build 1.236 Attention: Next.js now collects completely anonymous telemetry regarding usage. 1.236 This information is used to shape Next.js' roadmap and prioritize features. 1.236 You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL: 1.236 https://nextjs.org/telemetry 1.236 1.305 ▲ Next.js 15.3.2 1.305 - Environments: .env.production 1.305 1.322 Creating an optimized production build ... 12.24 ✓ Compiled successfully in 5.0s 12.25 Linting and checking validity of types ... 14.02 Collecting page data ... 18.59 Error: Unable to connect. Is the computer able to access the url? 18.59 at <anonymous> (.next/server/chunks/853.js:1:174236) 18.59 at <anonymous> (.next/server/chunks/853.js:3:9605) 18.59 at <anonymous> (.next/server/chunks/853.js:3:49033) 18.59 at processTicksAndRejections (null) 18.59 at <anonymous> (.next/server/chunks/853.js:3:21290) 18.59 at processTicksAndRejections (null) { 18.59 errno: 0, 18.59 path: 'http://backend:4200/api/', 18.59 code: 'ConnectionRefused', 18.59 config: [Object], 18.59 request: [Writable], 18.59 constructor: [Function], 18.59 toJSON: [Function: toJSON], 18.59 [cause]: [Error: Unable to connect. Is the computer able to access the url?] { 18.59 code: 'ConnectionRefused', 18.59 path: 'http://backend:4200/api/', 18.59 errno: 0 18.59 } 18.59 } 18.59 18.59 > Build error occurred 18.59 Error: Failed to collect page data for /users/[id] 18.59 at processTicksAndRejections (null) { 18.59 type: 'Error' 18.59 } 18.62 error: script "build" exited with code 1
解决方案
核心问题
前端构建阶段(RUN bun run build)是在Docker镜像构建过程中执行的,此时构建容器尚未加入docker-compose的默认网络,无法通过backend服务名访问已启动的后端容器。宿主机能访问localhost:4200,但构建容器与宿主机/后端容器不在同一网络环境,导致连接失败。
具体修复步骤
让构建容器接入宿主机网络
- 修改前端的docker-compose配置,在build字段中指定网络为host,或者直接用
host.docker.internal(Docker内置的宿主机映射地址)作为API域名:frontend: build: context: ./frontend network: host # 其他配置不变 - 同时将前端
.env.production中的API地址改为http://host.docker.internal:4200/api/,确保构建时能访问宿主机上的后端服务。
- 修改前端的docker-compose配置,在build字段中指定网络为host,或者直接用
脱离构建时的API依赖
- 如果
/users/[id]页面使用getStaticProps/getServerSideProps在构建时拉取数据,可调整为:- 改用增量静态再生(ISR),构建时不依赖实时API,运行时或定时更新数据
- 提前生成静态数据文件放入前端项目,构建时直接读取本地文件
- 给API请求添加降级逻辑,构建失败时返回模拟数据
- 如果
在宿主机完成前端构建
- 不在Docker内执行构建,先在宿主机运行
bun run build(确保后端已启动),再将构建好的.next文件夹复制到镜像中。修改前端Dockerfile:FROM oven/bun:latest WORKDIR /app COPY package*.json ./ RUN bun install COPY .next ./.next COPY public ./public COPY next.config.js ./ CMD ["bun", "start"] - 这样镜像构建仅复制静态文件,避免构建时调用API。
- 不在Docker内执行构建,先在宿主机运行
验证网络连通性
- 可在前端构建阶段临时添加测试命令,比如
RUN curl http://host.docker.internal:4200/api/,确认能访问后再执行build,快速排查网络问题。
- 可在前端构建阶段临时添加测试命令,比如
内容的提问来源于stack exchange,提问作者kirove
相关产品推荐
相关产品推荐

