Running a Mongo Replicaset Locally using Docker and Docker Compose
Tags: mongodb, testing, nosql
Published: 2022-03-30 22:00:23

## TLDR
* You can use Docker and Docker Compose to start a Mongo replica set locally
* [GitHub repo: docker-compose-mongo-replica-set](https://github.com/UpSync-Dev/docker-compose-mongo-replica-set)
* Use `docker-compose up -d` and off you go

## Docker Compose File
```yaml
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
```

## What is it?
* A way to run 3 instances of Mongo in a replica set on your machine
* This `docker-compose` setup starts a local mongo replica set with 3 instances running on: 
    - mongo1:30001
    - mongo2:30002
    - mongo3:30003

## Are there any prerequisites? 
• Docker
• Docker Compose
• The following in your `/etc/hosts` file:
```
127.0.0.1       mongo1
127.0.0.1       mongo2
127.0.0.1       mongo3
```

## How do I run the Replica Set?
Simples:
```
docker-compose up -d
```

## How do I access the Mongo Shells for each Instance?
```
docker exec -it mongo1 sh -c "mongo --port 30001"
docker exec -it mongo2 sh -c "mongo --port 30002"
docker exec -it mongo3 sh -c "mongo --port 30003"
```

## How does it work?
- Starts three instances of Mongo
- On the first instance it runs the following Mongo Shell command:

```javascript
rs.initiate(
  {
    s_id : 'my-replica-set',
    members: [
      { _id : 0, host : "mongo1:30001" },
      { _id : 1, host : "mongo2:30002" },
      { _id : 2, host : "mongo3:30003" }
    ]
  }
)
```
- This causes all 3 instances to join the replica set named `my-replica-set` and start talking to each other
- One is elected to become the `PRIMARY` and the other two become `SECONDARY` instances
- The Docker healthcheck config is used to cause the initialisation of the replica set. More info in the further reading links.

## Robo 3T
I used Robo 3T to test it locally and used the following config for the connection:

![Robo 3T Config](https://www.upsync.dev/assets/images/robo-3t.png)

## Acknowledgements / Further Reading
- [How to turn standalone MongoDB server into a replica set with Docker-Compose](https://zgadzaj.com/development/docker/docker-compose/turning-standalone-mongodb-server-into-a-replica-set-with-docker-compose)
- [Creating a MongoDB replica set using Docker 🍃](https://www.sohamkamani.com/blog/2016/06/30/docker-mongo-replica-set/)
- [asoorm/docker-compose-mongo-replicaset.yml](https://gist.github.com/asoorm/7822cc742831639c93affd734e97ce4f)

---
Cross posted from my blog [here](https://www.upsync.dev/2021/02/02/run-mongo-replica-set.html)