I'm trying to configure a mongodb replicaSet using docker-compose, but when I stop the master container it seems that it doesn't pass to the secondary.
redis: image: redis ports: - "6379:6379" mongo3: hostname: mongo3 image: mongo entrypoint: [ "/usr/bin/mongod", "--replSet", "rs", "--journal","--dbpath","/data/db","--smallfiles", "--rest" ] volumes: - ./data/mongo3:/data/db ports: - "27018:27017" - "28018:28017" restart: always mongo2: hostname: mongo2 image: mongo entrypoint: [ "/usr/bin/mongod", "--replSet", "rs", "--journal","--dbpath","/data/db","--smallfiles", "--rest" ] volumes: - ./data/mongo2:/data/db ports: - "27019:27017" - "28019:28017" restart: always mongo1: hostname: mongo1 image: mongo entrypoint: [ "/usr/bin/mongod", "--replSet", "rs", "--journal","--dbpath","/data/db","--smallfiles", "--rest" ] volumes: - ./data/mongo1:/data/db ports: - "27017:27017" - "28017:28017" links: - mongo2:mongo2 - mongo3:mongo3 restart: always web: build: . ports: - "2000:2000" volumes: - .:/vip links: - redis - mongo1 - mongo2 - mongo3 nginx: restart: always build: ./nginx/ ports: - "80:80" links: - web:web mongosetup: image: mongo links: - mongo1:mongo1 - mongo2:mongo2 - mongo3:mongo3 volumes: - ./scripts:/scripts entrypoint: [ "/scripts/setup.sh" ]
setup.sh :
#!/bin/bash MONGODB1=`ping -c 1 mongo1 | head -1 | cut -d "(" -f 2 | cut -d ")" -f 1` MONGODB2=`ping -c 1 mongo2 | head -1 | cut -d "(" -f 2 | cut -d ")" -f 1` MONGODB3=`ping -c 1 mongo3 | head -1 | cut -d "(" -f 2 | cut -d ")" -f 1` echo "**********************************************" ${MONGODB1} echo "Waiting for startup.." until curl http://${MONGODB1}:28017/serverStatus\?text\=1 2>&1 | grep uptime | head -1; do printf '.' sleep 1 done echo curl http://${MONGODB1}:28017/serverStatus\?text\=1 2>&1 | grep uptime | head -1 echo "Started.." echo SETUP.sh time now: `date +"%T" ` mongo --host ${MONGODB1}:27017 <<EOF var cfg = { "_id": "rs", "version": 1, "members": [ { "_id": 0, "host": "${MONGODB1}:27017", "priority": 2 }, { "_id": 1, "host": "${MONGODB2}:27017", "priority": 0 }, { "_id": 2, "host": "${MONGODB3}:27017", "priority": 0 } ],settings: {chainingAllowed: true} }; rs.initiate(cfg, { force: true }); rs.reconfig(cfg, { force: true }); rs.slaveOk(); db.getMongo().setReadPref('nearest'); db.getMongo().setSlaveOk(); EOF
A replica set in MongoDB is a group of mongod processes that maintain the same data set. Replica sets provide redundancy and high availability, and are the basis for all production deployments.
The docker compose up command aggregates the output of each container (like docker compose logs --follow does). When the command exits, all containers are stopped. Running docker compose up --detach starts the containers in the background and leaves them running.
I had a similar issue and resolved it with the following compose file:
version: "3.8" services: mongo1: image: mongo:4.2 container_name: mongo1 command: ["--replSet", "my-replica-set", "--bind_ip_all", "--port", "30001"] volumes: - ./data/mongo-1:/data/db ports: - 30001:30001 healthcheck: test: test $$(echo "rs.initiate({_id:'my-replica-set',members:[{_id:0,host:\"mongo1:30001\"},{_id:1,host:\"mongo2:30002\"},{_id:2,host:\"mongo3:30003\"}]}).ok || rs.status().ok" | mongo --port 30001 --quiet) -eq 1 interval: 10s start_period: 30s mongo2: image: mongo:4.2 container_name: mongo2 command: ["--replSet", "my-replica-set", "--bind_ip_all", "--port", "30002"] volumes: - ./data/mongo-2:/data/db ports: - 30002:30002 mongo3: image: mongo:4.2 container_name: mongo3 command: ["--replSet", "my-replica-set", "--bind_ip_all", "--port", "30003"] volumes: - ./data/mongo-3:/data/db ports: - 30003:30003
with the following in my /etc/hosts
file:
127.0.0.1 mongo1 127.0.0.1 mongo2 127.0.0.1 mongo3
I documented it in a GitHub repo and with a little blog post here:
https://github.com/UpSync-Dev/docker-compose-mongo-replica-set
https://www.upsync.dev/2021/02/02/run-mongo-replica-set.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With