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

Docker-Compose无法同时启动两个Node.js应用与MongoDB容器问题

解决Docker Compose同时启动两个Node.js应用与MongoDB容器的问题

问题描述

我有两个位于独立文件夹中的Node.js应用,尝试通过docker-compose运行这两个应用与一个MongoDB容器。

完整的docker-compose配置如下:

version: "3.8"
services:

  service-a:
    container_name: service-a
    build: ./service-a
    restart: unless-stopped
    ports:
      - '3000:3000'
    stdin_open: true
    tty: true
    depends_on:
      - mongo

  service-b:
    container_name: service-b
    build: ./service-b
    restart: unless-stopped
    ports:
      - '3001:3001'
    stdin_open: true
    tty: true
    depends_on:
      - mongo

  mongo:
    container_name: mongo
    image: mongo:latest
    ports:
      - '27017:27017'

volumes:
  db:

执行docker-compose up时无法同时启动三个容器,但注释掉其中一个应用后(如下配置)就能正常运行:

version: "3.8"
services:

  service-b:
    container_name: service-b
    build: ./service-b
    restart: unless-stopped
    ports:
      - '3001:3001'
    stdin_open: true
    tty: true
    depends_on:
      - mongo

  mongo:
    container_name: mongo
    image: mongo:latest
    ports:
      - '27017:27017'

volumes:
  db:

需要解决的问题:如何让三个容器同时运行,且两个Node.js应用都能连接到MongoDB容器?

附docker-compose up日志:

{
  "t": {
    "$date": "2022-11-15T14:32:20.034+00:00"
  },
  "s": "I",
  "c": "COMMAND",
  "id": 20499,
  "ctx": "ftdc",
  "msg": "serverStatus was very slow",
  "attr": {
    "timeStats": {
      "after basic": 248,
      "after activeIndexBuilds": 364,
      "after asserts": 526,
      "after batchedDeletes": 582,
      "after bucketCatalog": 726,
      "after catalogStats": 1007,
      "after connections": 1143,
      "after electionMetrics": 1434,
      "after extra_info": 1627,
      "after flowControl": 1658,
      "after freeMonitoring": 1715,
      "after globalLock": 1715,
      "after indexBulkBuilder": 1735,
      "after indexStats": 1735,
      "after locks": 1735,
      "after logicalSessionRecordCache": 1750,
      "after mirroredReads": 1750,
      "after network": 1775,
      "after opLatencies": 1775,
      "after opcounters": 1785,
      "after opcountersRepl": 1785,
      "after oplog": 1785,
      "after oplogTruncation": 1795,
      "after readConcernCounters": 1818,
      "after repl": 1903,
      "after scramCache": 2002,
      "after security": 2090,
      "after storageEngine": 2150,
      "after tcmalloc": 2239,
      "after tenantMigrations": 2239,
      "after trafficRecording": 2239,
      "after transactions": 2251,
      "after transportSecurity": 2251,
      "after twoPhaseCommitCoordinator": 2251,
      "after wiredTiger": 2382,
      "at end": 2716
    }
  }
}

解决步骤

1. 确保MongoDB就绪后再启动应用

depends_on仅保证容器启动顺序,不确保MongoDB服务完全就绪。两个应用同时启动时,可能在MongoDB还未初始化完成就发起连接,导致应用容器崩溃。

修改方案:

  • 给MongoDB添加健康检查,让应用等待其就绪后再启动:
    更新docker-compose中mongo服务的配置:
    mongo:
      container_name: mongo
      image: mongo:latest
      ports:
        - '27017:27017'
      healthcheck:
        test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
        interval: 5s
        timeout: 5s
        retries: 5
    
    同时修改两个应用的depends_on配置:
    service-a:
      # 其他配置保留
      depends_on:
        mongo:
          condition: service_healthy
    service-b:
      # 其他配置保留
      depends_on:
        mongo:
          condition: service_healthy
    
  • 在Node.js应用中添加连接重试逻辑(以mongoose为例):
    const mongoose = require('mongoose');
    
    const connectWithRetry = () => {
      mongoose.connect('mongodb://mongo:27017/your-db-name')
        .then(() => console.log('MongoDB连接成功'))
        .catch(err => {
          console.log('MongoDB连接失败,5秒后重试...', err);
          setTimeout(connectWithRetry, 5000);
        });
    };
    
    connectWithRetry();
    

2. 限制容器资源占用

日志显示MongoDB的serverStatus执行缓慢,说明宿主机CPU/内存资源可能不足,同时启动三个容器导致资源耗尽。

修改方案:
给每个容器添加资源限制,避免单个容器占用过多资源:

service-a:
  # 其他配置保留
  deploy:
    resources:
      limits:
        cpus: '0.5'
        memory: 512M
      reservations:
        cpus: '0.25'
        memory: 256M
service-b:
  # 其他配置保留
  deploy:
    resources:
      limits:
        cpus: '0.5'
        memory: 512M
      reservations:
        cpus: '0.25'
        memory: 256M
mongo:
  # 其他配置保留
  deploy:
    resources:
      limits:
        cpus: '1'
        memory: 1G
      reservations:
        cpus: '0.5'
        memory: 512M

3. 检查应用Dockerfile与连接字符串

  • 确认两个应用的Dockerfile正确配置,示例如下:
    FROM node:18-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    CMD ["node", "server.js"]
    
  • 应用中MongoDB连接字符串必须使用服务名mongo,不能用localhost:
    正确写法:mongodb://mongo:27017/your-db-name
    错误写法:mongodb://localhost:27017/your-db-name(容器内localhost指向自身,无法访问MongoDB容器)

4. 单独验证应用容器

分别单独构建并运行两个应用容器,确认它们能正常启动并连接MongoDB:

# 验证service-a
cd service-a
docker build -t service-a .
docker run --network=your-compose-network service-a

# 验证service-b同理
cd service-b
docker build -t service-b .
docker run --network=your-compose-network service-b

(your-compose-network可通过docker network ls查看,docker-compose默认会创建一个以项目名为前缀的网络)


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:10:23