在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,可分两步操作:
- 先启动MongoDB服务:
docker-compose up -d baza
- 等待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
相关产品推荐
相关产品推荐

