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

Docker容器自动终止问题求助:MongoDB副本集容器部署调试

用Docker Compose搭建MongoDB副本集(1主1从1仲裁)

我来帮你把这套MongoDB副本集的Docker配置梳理清楚,还会补充完整的docker-compose.yml文件,让你能快速搭建起测试环境:

1. 你的Dockerfile解析

先看你提供的Dockerfile,每一行的作用都很清晰:

FROM mongo:3.6.2
MAINTAINER Shanty
RUN apt-get update && apt-get install -y netcat
COPY ./.docker/mongo_scripts /mongo_scripts
RUN chmod +rx /mongo_scripts/*.sh
EXPOSE 27091 27092 27093
ENTRYPOINT ["/mongo_scripts/rs.sh"]
  • FROM mongo:3.6.2:基于官方稳定的MongoDB 3.6.2镜像作为基础
  • RUN apt-get update && apt-get install -y netcat:安装netcat工具,用来检测MongoDB服务是否就绪,这对副本集初始化至关重要
  • COPY ./.docker/mongo_scripts /mongo_scripts:把本地的初始化脚本目录复制到容器内
  • RUN chmod +rx /mongo_scripts/*.sh:给脚本添加执行和读取权限,确保容器启动时能正常运行脚本
  • EXPOSE 27091 27092 27093:暴露三个端口,对应副本集的主、从、仲裁节点
  • ENTRYPOINT ["/mongo_scripts/rs.sh"]:指定容器启动时优先执行副本集初始化脚本

小建议:现在Docker官方更推荐用LABEL maintainer="Shanty"替代MAINTAINER指令,你可以根据需要调整。

2. 完善副本集初始化脚本(rs.sh)

你只写了脚本开头,我帮你补全完整的逻辑,确保副本集能正确初始化:

#!/bin/bash
set -e

# 等待MongoDB服务启动就绪的工具函数
wait_for_mongo() {
  local host=$1
  local port=$2
  echo "等待MongoDB服务在${host}:${port}就绪..."
  while ! nc -z "$host" "$port"; do
    sleep 1
  done
  echo "MongoDB服务${host}:${port}已就绪"
}

# 根据节点角色启动对应配置的MongoDB服务
if [ "$NODE_ROLE" = "primary" ]; then
  # 启动主节点MongoDB,指定副本集名称和绑定所有IP
  mongod --port 27091 --dbpath /data/db --replSet rs0 --bind_ip_all &
  MONGO_PID=$!
  wait_for_mongo localhost 27091

  # 初始化副本集配置
  mongo --port 27091 <<EOF
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo-primary:27091" },
    { _id: 1, host: "mongo-secondary:27092" },
    { _id: 2, host: "mongo-arbiter:27093", arbiterOnly: true }
  ]
})
EOF
elif [ "$NODE_ROLE" = "secondary" ]; then
  # 启动从节点MongoDB,等待加入副本集
  mongod --port 27092 --dbpath /data/db --replSet rs0 --bind_ip_all &
  MONGO_PID=$!
  wait_for_mongo localhost 27092
elif [ "$NODE_ROLE" = "arbiter" ]; then
  # 启动仲裁节点MongoDB,等待加入副本集
  mongod --port 27093 --dbpath /data/db --replSet rs0 --bind_ip_all &
  MONGO_PID=$!
  wait_for_mongo localhost 27093
fi

# 保持容器前台运行,避免启动后自动退出
wait $MONGO_PID

这个脚本的核心逻辑:

  • set -e:遇到错误立即退出,避免无效的后续操作
  • wait_for_mongo:用netcat检测端口,确保MongoDB完全启动后再执行初始化
  • 根据NODE_ROLE环境变量区分节点类型,主节点负责初始化副本集,从节点和仲裁节点只需要启动服务等待加入
  • 最后用wait $MONGO_PID让容器保持运行状态

3. 完整的docker-compose.yml配置

有了Dockerfile和脚本,还需要docker-compose.yml来编排三个节点:

version: '3.7'

services:
  mongo-primary:
    build: .
    container_name: mongo-primary
    environment:
      - NODE_ROLE=primary
    ports:
      - "27091:27091"
    volumes:
      - primary-data:/data/db
    networks:
      - mongo-cluster

  mongo-secondary:
    build: .
    container_name: mongo-secondary
    environment:
      - NODE_ROLE=secondary
    ports:
      - "27092:27092"
    volumes:
      - secondary-data:/data/db
    networks:
      - mongo-cluster
    depends_on:
      - mongo-primary

  mongo-arbiter:
    build: .
    container_name: mongo-arbiter
    environment:
      - NODE_ROLE=arbiter
    ports:
      - "27093:27093"
    volumes:
      - arbiter-data:/data/db
    networks:
      - mongo-cluster
    depends_on:
      - mongo-primary

volumes:
  primary-data:
  secondary-data:
  arbiter-data:

networks:
  mongo-cluster:
    driver: bridge

配置说明:

  • 三个服务分别对应主、从、仲裁节点,共用同一个Dockerfile构建镜像
  • 通过NODE_ROLE环境变量传递节点类型给初始化脚本
  • 每个节点挂载独立的Docker卷,避免容器销毁后数据丢失
  • 自定义mongo-cluster网络,让节点之间可以通过容器名(如mongo-primary)直接通信
  • depends_on确保主节点先启动,但真正的服务就绪检测还是靠脚本里的wait_for_mongo

4. 启动和验证步骤

  1. 构建并启动所有容器:
docker-compose up -d --build
  1. 验证副本集状态:
    进入主节点容器,连接MongoDB后查看状态:
docker exec -it mongo-primary mongo --port 27091
> rs.status()

你应该能看到三个节点都处于PRIMARY、SECONDARY、ARBITER的正常状态。

  1. 验证主从同步:
    在主节点插入测试数据:
> db.test_collection.insert({name: "test_data"})

然后进入从节点容器,开启从节点查询权限后查看数据:

docker exec -it mongo-secondary mongo --port 27092
> rs.slaveOk()
> db.test_collection.find()

能看到刚才插入的测试数据,就说明主从同步正常了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:35:03