Search code examples
mongodbdocker-composereplicaset

Docker-compose MongoDB replicaset with admin user


I am struggling to find a simple configuration that deliver a single-node replica set and mongo-express with docker-compose, with admin authentication enabled. Here where I am stuck:

docker-compose.yml

services:
  mongo:
    image: mongo:5.0.2-focal
    container_name: mongo
    restart: always
    ports:
      - 27017:27017
    volumes:
      - ./scripts/mongo-init-rset.sh:/mongo-init-rset.sh
    command: ./mongo-init-rset.sh

  mongo-express:
    image: mongo-express
    container_name: mongo-express
    restart: always
    depends_on:
    - mongo
    ports:
        - ${MONGOEXP_PORT:-8081}:8081
    environment:
      ME_CONFIG_MONGODB_SERVER: mongo
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: root

./scripts/mongo-init-rset.sh

#!/bin/bash

# NOTE: this script does not force Auth on Mongo, but will allow root and other users to authenticate.
# WARNING: unauthenticated users can still log in.

start_mongo() {
    mongod --replSet rs0 --bind_ip_all
}

activate_rs() {
    echo "Waiting for Mongo to start..."
    sleep 5
    echo "INITIATE REPLICA SET"
    mongosh --host mongo --eval "rs.initiate()"
    echo "MAKE ADMIN USER FOR REPLICA SET"
    mongosh --host mongo --eval "db.createUser({ user: \"root\", pwd: \"root\", roles: [ { role: \"root\", db: \"admin\" } ] });" admin
}

start_mongo & activate_rs

Note: MONGO_INITDB_ROOT_USERNAME and MONGO_INITDB_ROOT_PASSWORD are not in mongo environment since they were ignored.


Solution

  • You should wait for replicaset to be initiated. Something like this, for example:

    rs.initiate()
    rs.status()
    while (! db.isMaster().ismaster ) { sleep(1000) }
    // Now you can create the admin user