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

Docker Compose构建NextJS应用时MongoDB与Redis连接失败

NextJS + Docker Compose构建阶段无法连接MongoDB/Redis的问题

我有一个基于NextJS的应用,使用MongoDB和Redis作为数据存储,尝试通过Docker Compose部署时遇到问题:在NextJS构建的Generating static pages阶段,应用需要连接Redis和MongoDB获取静态页面数据,但此时这两个服务的容器尚未启动,导致连接失败,出现以下错误:

Redis连接错误

42.85 [ioredis] Unhandled error event: Error: getaddrinfo ENOTFOUND redis_pishrun
42.85     at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26)
42.85     at GetAddrInfoReqWrap.callbackTrampoline (node:internal/async_hooks:128:17)

MongoDB连接错误

73.84 MongooseServerSelectionError: getaddrinfo ENOTFOUND mongo_pishrun
73.84     at _handleConnectionErrors (/app/node_modules/mongoose/lib/connection.js:909:11)
73.84     at NativeConnection.openUri (/app/node_modules/mongoose/lib/connection.js:860:11) {
73.84   reason: TopologyDescription {
73.84     type: 'Unknown',
73.84     servers: Map(1) { 'mongo_pishrun:27017' => [ServerDescription] },
73.84     stale: false,
73.84     compatible: true,
73.84     heartbeatFrequencyMS: 10000,
73.84     localThresholdMS: 15,
73.84     setName: null,
73.84     maxElectionId: null,
73.84     maxSetVersion: null,
73.84     commonWireVersion: 0,
73.84     logicalSessionTimeoutMinutes: null
73.84   },
73.84   code: undefined,
73.84   digest: '2271496410'
73.84 }

我的配置文件

docker-compose.yml

version: '3.8'

services:
  pishrun-next:
    container_name: pishrun-next
    restart: always
    build:
      context: .
      dockerfile: Dockerfile
      args:
        ENV_VARIABLE: ${ENV_VARIABLE}
        NEXT_PUBLIC_ENV_VARIABLE: ${NEXT_PUBLIC_ENV_VARIABLE}
    ports:
      - '3000:3000'
    networks:
      - shared_network
    depends_on:
      - mongo_pishrun
      - redis_pishrun


  mongo_pishrun:
    image: mongo:latest
    container_name: mongo_pishrun
    restart: always
    ports:
      - '27017:27017'
    volumes:
      - mongo_pishrun_data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=Aa!23456
    networks:
      - shared_network

  redis_pishrun:
    image: redis:latest
    container_name: redis_pishrun
    restart: always
    ports:
      - '6379:6379'
    networks:
      - shared_network
    volumes:
      - redis_pishrun_data:/data


volumes:
  mongo_pishrun_data:
    driver: local
  redis_pishrun_data:
    driver: local

networks:
  shared_network:
    external: true

NextJS应用的Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN npm i
COPY . .

ARG ENV_VARIABLE
ENV ENV_VARIABLE=${ENV_VARIABLE}
ARG NEXT_PUBLIC_ENV_VARIABLE
ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE}

RUN npm run build
CMD npm run start

已尝试的解决方案

  • 为容器创建共享网络
  • 单独运行Redis和MongoDB容器后再构建NextJS容器
  • 在构建过程中添加网络作为构建参数:docker compose -f docker-compose.yml build --build-arg NETWORK=shared_network

问题仍未解决,Docker构建阶段似乎无法访问Docker网络。


解决方案

核心原因

Docker的构建阶段与运行阶段完全隔离:构建过程在临时构建容器中执行,该容器不会自动加入docker-compose定义的网络,因此即使提前启动MongoDB/Redis容器,构建阶段也无法通过容器名解析到对应服务。

可行方案

方案1:本地预构建静态产物,再打包镜像

在本地环境(或CI/CD环境)先完成NextJS构建(确保本地能连接MongoDB/Redis获取数据),再将构建产物复制到镜像中,避免在镜像构建阶段执行build命令。修改Dockerfile:

FROM node:18-alpine

WORKDIR /app

# 复制预构建的静态产物
COPY .next/ .next/
COPY public/ public/
COPY package.json ./

ARG ENV_VARIABLE
ENV ENV_VARIABLE=${ENV_VARIABLE}
ARG NEXT_PUBLIC_ENV_VARIABLE
ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE}

# 只安装生产依赖
RUN npm install --production

CMD npm run start

执行流程:本地运行npm run build → 执行docker compose build → docker compose up

方案2:用Docker Buildkit让构建阶段加入现有网络

启用Docker Buildkit,让构建阶段的容器加入已存在的shared_network,从而能访问MongoDB/Redis服务:

  1. 确保Buildkit已启用(通过环境变量DOCKER_BUILDKIT=1开启)
  2. 修改docker-compose.yml的build配置,添加network字段:
build:
  context: .
  dockerfile: Dockerfile
  args:
    ENV_VARIABLE: ${ENV_VARIABLE}
    NEXT_PUBLIC_ENV_VARIABLE: ${NEXT_PUBLIC_ENV_VARIABLE}
  network: shared_network
  1. 提前启动MongoDB和Redis容器:docker compose up -d mongo_pishrun redis_pishrun
  2. 执行构建命令:
DOCKER_BUILDKIT=1 docker compose build

方案3:改用NextJS增量静态再生(ISR)

修改页面的静态生成逻辑,使用增量静态再生,让页面在首次请求时生成,而非构建阶段。这样构建阶段无需依赖外部服务,运行时再获取数据。示例:

export async function getStaticProps() {
  // 从MongoDB/Redis获取数据的逻辑
  const data = await fetchRequiredData();
  
  return {
    props: { data },
    // 每60秒自动重新生成页面(可按需调整)
    revalidate: 60,
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:46:02