MongoDB cluster using docker compose

  • March 15, 2023
  • 2 min read

Deploy MongoDB Replica Set With Keyfile Authentication on docker compose environment.

Keyfile Authentication

To use authentication with cluster, need to generate a keyfile. This can easily generate using

openssl rand -base64 756 > file.key
chmod 400 file.key

For production MongoDB encourage to use x.509 Certificate Authentication For MongoDB enterprise edition use LDAP proxy or kerboros for authentication, if not x.509 certs.

Docker-Compose file

version: '3.8'

services:
  mongo1:
    container_name: mongo1
    image: mongo:5.0.13
    volumes:
      - ./data/mongo1:/data/db
      - ./file.key:/data/file.key
    networks:
      - int-network
    environment:
      - MONGO_INITDB_ROOT_USERNAME=db_user
    # Generate a new password
      - MONGO_INITDB_ROOT_PASSWORD=2R8SzLme7EMaSHMk
    ports:
      - 27017:27017
    depends_on:
      - mongo2
      - mongo3
    links:
      - mongo2
      - mongo3
    restart: always
    entrypoint: [ "/usr/bin/mongod", "--keyFile", "/data/file.key", "--bind_ip_all", "--replSet", "cluster0" ]

  mongo2:
    container_name: mongo2
    image: mongo:5.0.13
    volumes:
      - ./data/mongo2:/data/db
      - ./file.key:/data/file.key
    networks:
      - int-network
    ports:
      - 27018:27017
    restart: always
    entrypoint: [ "/usr/bin/mongod", "--keyFile", "/data/file.key", "--bind_ip_all", "--replSet", "cluster0" ]
  mongo3:
    container_name: mongo3
    image: mongo:5.0.13
    volumes:
      - ./data/mongo3:/data/db
      - ./file.key:/data/file.key
    networks:
      - int-network
    ports:
      - 27019:27017
    restart: always
    entrypoint: [ "/usr/bin/mongod", "--keyFile", "/data/file.key", "--bind_ip_all", "--replSet", "cluster0" ]

networks:
 int-network:
   external: true

Use following bash script to start the cluster. This will initalize cluster as well as enable login

DELAY=15

docker compose up -d

sleep $DELAY

docker exec -it mongo1 mongosh --eval "rs.initiate({
 _id: \"cluster0\",
 members: [
   {_id: 0, host: \"mongo1\", priority: 2},
   {_id: 1, host: \"mongo2\", priority: 1},
   {_id: 2, host: \"mongo3\", priority: 1}
 ]
})"

sleep $DELAY

docker exec -it mongo1 mongosh --eval "db.getSiblingDB('admin').createUser({
  user: 'admin_user',
  pwd: '2R8SzLme7EMaSHMk',
  roles: [
    { role: 'userAdminAnyDatabase', db: 'admin' },
    { role: 'clusterAdmin', db: 'admin' },
  ],
});
"

docker exec -it mongo1 mongosh -u admin_user -p 2R8SzLme7EMaSHMk --eval "db.getSiblingDB('admin').createUser(
  {
    user : 'shlk_db_user',
    pwd : '8SzLme7EMaSHMk',
    roles: [ { role : 'readWriteAnyDatabase', db:'admin' } ]
  }
)"

sleep $DELAY

docker exec -it mongo1 mongosh -u admin_user -p 2R8SzLme7EMaSHMk --eval "rs.status()"

Using mongosh with cluster

docker exec -it mongo1 mongosh -u db_user -p 8SzLme7EMaSHMk

Enable monitoring

docker exec -it mongo1 mongosh --eval "db.enableFreeMonitoring()"