You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Docker Compose中使用Next.js getStaticProps:构建时MongoDB连接失败

问题:Docker Compose构建Next.js容器时无法连接MongoDB

我正在开发一个使用Next.js的API Routes和getStaticProps特性的应用,想通过docker-compose部署全栈项目。但每次构建Web应用容器都会失败,原因是构建阶段无法连接到数据库容器获取props。试过wait-for-it.sh、depends_on、healthcheck、在Dockerfile中添加等待脚本,甚至拆分组件到不同yaml文件,都没有效果。

需求

  • 启动MongoDB并通过mongo-init.js完成数据初始化(此部分已正常工作)
  • 等待MongoDB容器完全就绪后,再开始Next.js容器的构建流程

这种配置是否可行?有没有办法在第一个容器启动并运行后再开始构建镜像?


当前Dockerfile

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . ./
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]

当前docker-compose.yml(包含多次尝试的配置)

version: "2.4"

services:  
  baza:
    container_name: baza
    image: mongo:latest
    restart: always
    environment:
        MONGO_INITDB_ROOT_USERNAME: <secret_login>
        MONGO_INITDB_ROOT_PASSWORD: <secret_password>
        MONGO_INITDB_DATABASE: ITM
    ports:
        - 27017:27017
    volumes:
        - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
        - ./MongoITM:/data/db
    networks:
        - siec-kontenerow-ITM

  strona:
    container_name: strona
    restart: always
    # volumes:
    #   - ./:/usr/src/app
    env_file: .env
    ports:
      - "80:3000"
    networks:
      - siec-kontenerow-ITM
     # - nextjs
    # healthcheck:
    #   test: curl --fail http://baza:27017 || exit 1
    #   interval: 30s
    #   timeout: 10s
    #   retries: 5
    # depends_on:
    #   - baza
    
    build:
      context: .
      dockerfile: Dockerfile
    
    # command: ["./wait-for-it.sh", "baza:27017", "--", "npm", "start"]
        
    
networks:
  siec-kontenerow-ITM: 
    driver: bridge

构建错误代码片段

/app/node_modules/mongodb/lib/sdam/topology.js:278
51.09                 const timeoutError = new error_1.MongoServerSelectionError(`Server selection timed out after ${serverSelectionTimeoutMS} ms`, this.description);
51.09                                      ^
51.09 
51.09 MongoServerSelectionError: connection timed out
51.09     at Timeout._onTimeout (/app/node_modules/mongodb/lib/sdam/topology.js:278:38)
51.09     at listOnTimeout (node:internal/timers:569:17)
51.09     at process.processTimers (node:internal/timers:512:7) {
51.09   reason: TopologyDescription {
51.09     type: 'Unknown',
51.09     servers: Map(1) {
51.09       'localhost:27017' => ServerDescription {

解决方案

核心问题分析

Docker Compose的build阶段是在容器启动前执行的,此时MongoDB容器尚未创建,也未加入网络,所以你之前尝试的depends_on、wait-for-it.sh等都是针对容器启动阶段的配置,对构建阶段完全无效。另外错误日志显示连接的是localhost:27017,但构建阶段的localhost指的是构建容器本身,而非MongoDB容器,这也是连接失败的关键原因。

可行方案

方案1:分离构建与运行逻辑,避免构建时依赖数据库

如果你的业务允许,可调整Next.js的数据获取方式:

  • 改用getServerSideProps:将数据获取逻辑移到请求阶段,构建阶段无需连接数据库,待容器启动后,再用wait-for-it.sh等待MongoDB就绪后处理请求。
  • 提前生成静态数据:在构建前通过脚本从MongoDB导出数据到本地文件,构建时直接读取本地文件,无需连接数据库。

方案2:手动分阶段执行,先启动MongoDB再构建镜像

如果必须在构建时连接MongoDB,可分两步操作:

  1. 先启动MongoDB服务:
docker-compose up -d baza
  1. 等待MongoDB完全就绪(可通过mongosh测试连接),再构建并启动Next.js容器:
docker-compose up --build strona

方案3:修正数据库连接地址

无论采用哪种方案,都要确保Next.js连接MongoDB时使用容器名称baza作为主机名,而非localhost。检查.env文件中的连接字符串:

MONGODB_URI=mongodb://<secret_login>:<secret_password>@baza:27017/ITM?authSource=admin

内容的提问来源于stack exchange,提问作者T3chnoM4ciej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:57:48