Use case: add an init script to the Docker official Mongo image
How to create additionnal users, initialize collections and indexes at build time
While playing around with mongo db on my dev environnement, I used the latest official image of mongo.
Having a look at the dockerfile provided, I found that the maintainers had the good idea to give us the possibility to initialize our new built mongo database.
At the end of the dockerfile, an entrypoint set up the image and gives the developper room to customize the database.
# Dockerfile
ENTRYPOINT ["docker-entrypoint.sh"]
docker-entrypoint.sh is processed to build the image. You can supply two environnement variables that will be your credentials as the root user in your docker-compose file.
# docker-entrypoint.sh
"${mongo[@]}" "$rootAuthDatabase" ;-EOJS
db.createUser({
user: $(jq --arg 'user' "$MONGO_INITDB_ROOT_USERNAME" --null-input '$user'),
pwd: $(jq --arg 'pwd' "$MONGO_INITDB_ROOT_PASSWORD" --null-input '$pwd'),
roles: [ { role: 'root', db: $(jq --arg 'db' "$rootAuthDatabase" --null-input '$db') } ]
})
EOJS
Another perks of this entrypoint is that if you share a folder docker-entrypoint-initdb.d, all js or sh files will be executed at built time.
# docker-entrypoint.sh
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
To benefit from this neat trick, that’s how our docker-compose.yaml could look like.
# docker-compose.yaml
version: "3"
services:
mongo:
image: "mongo:3"
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USERNAME}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD}
volumes:
- "./mongo/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d"
In the host folder /mongo/docker-entrypoint-initdb.d, we can add as many sh and js files to customize your mongo db.