docker-compose create mongo container with username and password

I have a mongo container being created in Compose:

version: '2'
volumes:
  mongodata:
    driver: local
services:
  mongo:
    image: mongo:latest
    hostname: ${MONGODB_HOST}
    restart: always
    ports: 
      - "27017:27017"
    volumes:
      - mongodata:/data/db

This works perfectly, however now I want to put a password on the database. To do so, firstly as I understand it I need to create the database, add a password, then restart it with the --auth flag. My question is how to do this process with docker-compose.

I can do this if I do everything without docker-compose. The issues that I can see arising with compose are:

a) docker-compose works inside a docker network. b) docker-compose can't run different commands at the beginning as during production. - this is important because although some people say that you can run --auth at the beginning and it will allow you to set a password the first time, this doesn't seem to be the case.

One solution I began working on was a shell script I would run on all my servers before running docker-compose file:

# start the temporary container
docker run -d -v /tmp/mongodb --name tmpdb -e MONGODB_DBNAME=db_test mongo --auth
# do the user creation
docker run -it --link tmpdb --rm mongo sh -c 'mongo --host tmpdb --eval "db.createUser({ user: \"admin\", pwd: \"password\", roles: [ { role: \"root\", db: \"admin\" } ] });"'
# stop the server
docker stop tmpdb
# create new mongodb container, using the old ones data
docker run -d -p 27017:27017 --name mongo2 -e MONGODB_DBNAME=db_test mongo --auth
# clean up old container (we are using the volumes so they will stick around)
docker rm tmpdb

This file creates a temporary container, sets a username/password on it, stops the original container, creates a new one using the old ones volume container, and deletes the original one. The new mongo container now has a password on.

So my conclusive question is, whats the best way to do this in docker-compose?

My other containers in my docker-compose file need to be able to access mongo so i think the volume container holding the mongo data needs to be in the same network that the docker-compose creates


The mongo:latest image at the time of writing (v 3.5) accepts two environment variables, MONGO_INITDB_ROOT_USERNAME and MONGO_INITDB_ROOT_PASSWORD.

When these are set, the container's entrypoint script will start the mongod service with --auth, then create an admin user with the provided credentials.

This is currently not documented in their README, but there's a GitHub issue tracking progress on that matter, and the source is available on line 104 of the docker-entrypoint.sh script.

To use these variables in your docker-compose.yml, see the following snippet:

version: '3'
services:
  mongodb:
    image: mongo:3.5
    hostname: ${MONGODB_HOST}
    environment:
      - MONGO_INITDB_ROOT_USERNAME=alice
      - MONGO_INITDB_ROOT_PASSWORD=super-secret-password
    restart: on-failure
    ports:
      - 27017:27017
    volumes:
      - ./mongodb:/data/db