必须使用自定义docker网络,因默认bridge下容器无法通过宿主机ip互连,导致rs.initiate()失败;各节点需统一--replset名称(如rs0)、相同lts镜像版本、固定container_name、挂载数据卷,并在rs.initiate()中填写容器名:27017格式的host地址。

能直接跑起来,但默认桥接网络下容器间无法用宿主机 IP 互连,rs.initiate() 会失败——必须用自定义网络或显式指定可互通地址。
启动三个带 --replSet 的容器
每个节点必须用相同副本集名(如 rs0),且镜像版本一致(推荐 mongo:6.0.18 或 mongo:7.0.4 LTS):
- 端口映射不能全映射到
27017:宿主机需区分,例如-p 27017:27017、-p 27018:27017、-p 27019:27017 - 必须挂载数据卷,否则重启后数据丢失:
-v ./mongo1/data:/data/db - 不加
--replSet rs0参数的容器无法加入副本集,哪怕名字一样也不行 - 不要用
latest标签,不同拉取时间可能拿到不兼容版本
用 docker-compose 自建网络(最省事)
默认 bridge 网络下,容器只能通过容器名通信,但外部客户端连接时用的是宿主机 IP + 映射端口,而 rs.initiate() 配置里写的地址必须能让所有成员互相访问——自定义网络自动解决这个矛盾:
- 在
docker-compose.yml中声明networks并让所有服务加入同一网络 -
services下每个 MongoDB 实例用container_name固定名称(如mongo1),这样配置里可写"mongo1:27017" - 不需要额外开防火墙或改
bind_ip,官方镜像默认监听0.0.0.0 - 如果硬要用
docker run手动启,得加--network mynet并提前docker network create mynet
执行 rs.initiate() 时的 host 地址怎么填
填错就导致成员连不上,状态卡在 STARTUP 或报 Connection refused:
- 在自定义网络中,填容器名 + 内部端口(如
"mongo1:27017"),不是宿主机 IP - 如果用宿主机 IP(如
"192.168.1.100:27017"),所有容器都得能路由到该地址——Docker Desktop for Mac/Windows 默认不满足 -
_id字段必须和启动参数--replSet的值完全一致(大小写敏感) - 初始化后立刻执行
rs.status(),检查members[n].stateStr是否为"PRIMARY"或"SECONDARY",而非"STARTUP2"或"RECOVERING"
最容易被忽略的是:副本集成员之间必须能双向 TCP 连通(不只是 ping 通),且 MongoDB 实例未启用 auth 时,rs.initiate() 才允许执行;一旦加了 --keyFile 或 --auth,就得先创建用户再初始化,顺序错了整个流程就卡住。











