hjr265.me / blog /

Single Node MongoDB Replica Set with Docker Compose

Toph needs a few MongoDB features that only work in replica set mode. Take Change Streams, for example. It is unavailable in standalone mode.

To ease development, all of Toph’s application codebases come with Docker Compose files. With just a single docker-compose up, I can have any of Toph’s applications running in a development environment. But having MongoDB start in replica set mode has been a bit of work.

You see, simply starting three nodes and then going in to configure them to be in a replica set wasn’t something I wanted to do. I wanted only a single node to run, and I wanted it to start in replica mode, even if I was running docker-compose up on a freshly installed machine.

So here is what I had to do:

1. Add MongoDB to docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
services:
  # ...
  mongo:
    build:
      context: devel/mongodb
      dockerfile: Dockerfile
    hostname: mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=secret
      - MONGO_INITDB_USERNAME=cat
      - MONGO_INITDB_PASSWORD=keyboard
      - MONGO_INITDB_DATABASE=databez
    volumes:
      - mongo:/data/db
    command: --keyFile /etc/keyfile --replSet rs0 --bind_ip_all

  # Sets up a single node replica set.
  mongoinit:
    image: mongo:6.0
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=secret
    volumes:
      - ./devel/mongodb/init.sh:/init.sh
    entrypoint: ["bash", "/init.sh"]
    depends_on:
      - mongo

2. Add Dockerfile to devel/mongodb/

1
2
3
4
5
6
FROM mongo:6.0

COPY --chown=999:999 initdb.d/10-createuser.sh /docker-entrypoint-initdb.d/10-createuser.sh
COPY --chown=999:999 keyfile /etc/keyfile

CMD ["--keyFile", "/etc/keyfile", "--replSet", "rs0", "--bind_ip_all"]

3. Add 10-createuser.sh to devel/mongodb/initdb.d/

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/bash

set -Eeuo pipefail
 
mongo -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin "$MONGO_INITDB_DATABASE" <<EOF
    db.createUser({
        user: '$MONGO_INITDB_USERNAME',
        pwd: '$MONGO_INITDB_PASSWORD',
        roles: [
            {
                role: 'readWrite',
                db: '$MONGO_INITDB_DATABASE'
            }
        ]
    })
EOF

4. Generate a keyfile for MongoDB Replica Set:

1
2
openssl rand -base64 756 > ./devel/mongodb/keyfile
chmod 400 ./devel/mongodb/keyfile

And, We Are Done!

You can now start the containers with Docker Compose:

1
docker-compose up

This post is 4th of my #100DaysToOffload challenge. Want to get involved? Find out more at 100daystooffload.com.

Table Of Contents

comments powered by Disqus