Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: September 19, 2024
MongoDB is a widely used NoSQL database, known for its flexibility in managing unstructured data. When working with Docker containers, automating the initialization of MongoDB can simplify deployment and ensure consistency across environments. In particular, with Docker Compose, we can set up MongoDB to create databases and users on startup streamlining the process.
In this tutorial, we’ll learn how to create a MongoDB container that automatically initializes a database upon startup. We’ll explore various methods, including using Docker Compose with a JavaScript initialization script and different techniques for customizing the setup with environment variables.
We use Docker Compose to create MongoDB containers on startup.
To begin, let’s create the docker-compose file that defines the MongoDB service:
version: '5.0'
services:
mongodb:
image: mongo:latest
container_name: mongodb
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: mydatabase
ports:
- 27017:27017
volumes:
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
This configuration file contains the following information:
The file configures the MongoDB container, specifies environment variables, and maps ports.
Additionally, now that the docker-compose.yml file is ready, let’s write the initialization script (mongo-init.js) to automate user and database creation:
db.createUser({
user: "dbuser",
pwd: "dbpassword",
roles: [{
role: "readWrite",
db: "mydatabase"
}]
});
In the script, we create a new user (dbuser) with a password (dbpassword). Then, we assign the readWrite role to the user for the specific database (mydatabase).
Furthermore, MongoDB runs this script during container initialization if the database has not been previously set up.
Once the docker-compose.yml and mongo-init.js files are ready, we can start the MongoDB container to build and run the service:
$ docker-compose up --build -d mongodb
[+] Running 9/9
✔ mongodb 8 layers [⣿⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 225.1s
✔ 857cc8cb19c0 Pull complete 37.2s
✔ a54f12bd5819 Pull complete 1.0s
✔ f95b02a6236d Pull complete 1.7s
✔ 0d20d29fe9ca Pull complete 4.4s
✔ 2382733f40de Pull complete 3.3s
✔ c1458145b657 Pull complete 4.5s
✔ fee77be41765 Pull complete 207.6s
✔ da4a4cbb623f Pull complete 5.6s
[+] Running 1/2
⠴ Network mongodb-container_default Created 1.4s
✔ Container mongodb Started
With this command, we built the MongoDB image and started the MongoDB container in detached mode. Finally, ensure the initialization script runs, creating the database and user during startup.
Additionally, let’s confirm the MongoDB startup by connecting to the MongoDB container using the mongo shell:
$ mongo --host localhost --port 27017 -u admin -p password --authenticationDatabase admin
MongoDB shell version v6.1.1
connecting to: mongodb://localhost:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("b983f22c-b0d3-4f89-a148-746c593c87e9") }
MongoDB server version: 7.0.14
...
Then, let’s check if the mydatabase was created and whether the dbuser was added successfully:
use mydatabase;
switched to db mydatabase
db.getUsers();
[
{
"_id" : "mydatabase.dbuser",
"userId" : UUID("db67dfa5-7ed5-4105-9de8-cd34c61ac05d"),
"user" : "dbuser",
"db" : "mydatabase",
"roles" : [
{
"role" : "readWrite",
"db" : "mydatabase"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
]
From the output, it displays a successful switch to the mydatabase database and also lists dbuser among users. This confirms that the MongoDB container has initialized as expected.
In some cases, using a shell script to configure MongoDB may be more practical, especially when environment variables are involved.
Firstly, let’s write a shell script that uses environment variables to configure MongoDB and create users:
#!/bin/bash
MONGO_USER="user"
MONGO_PASSWORD="userpasswd"
# Prepare the user credentials for MongoDB
q_MONGO_USER=$(jq --arg v "$MONGO_USER" -n '$v')
q_MONGO_PASSWORD=$(jq --arg v "$MONGO_PASSWORD" -n '$v')
# Run MongoDB commands
mongo -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" admin <<EOF
use mydatabase;
db.createUser({
user: $q_MONGO_USER,
pwd: $q_MONGO_PASSWORD,
roles: ["readWrite"],
});
EOF
The script contains the following information:
To run this script during the MongoDB container’s initialization, we need to modify the docker-compose.yml file to include the shell script:
version: '5.0'
services:
mongodb:
image: mongo:latest
container_name: mongodb
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: mydatabase
ports:
- 27017:27017
volumes:
- ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh:ro
In this configuration, we add the init-mongo.sh script to the /docker-entrypoint-initdb.d/ directory. In particular, it ensures the script runs during the container’s initialization process.
Afterward, we can start the container with the same command:
$ docker-compose up --build -d mongodb
Once the container starts, the script will automatically run, creating the user and initializing the database.
Another way to handle MongoDB initialization is by creating a custom Dockerfile. This method builds a custom image incorporating the initialization script and environment variables.
The following Dockerfile extends the official MongoDB image and customizes it by including environment variables and an initialization script:
FROM mongo:latest
# Set environment variables for MongoDB root user and password
ENV MONGO_INITDB_ROOT_USERNAME=admin
ENV MONGO_INITDB_ROOT_PASSWORD=password
# Copy the initialization script to the container's init directory
COPY mongo-init.js /docker-entrypoint-initdb.d/
The Dockerfile contains the following information:
We can proceed to create the initialization script.
We create the mongo-init.js script, which MongoDB will automatically execute during startup. This script can contain the commands necessary to initialize the database and create users:
db.createUser({
user: "user",
pwd: "userpasswd",
roles: [
{ role: "readWrite", db: "mydatabase" }
]
});
The script creates a user with the readWrite role in the mydatabase database.
Once the Dockerfile and initialization script are in place, we can build the custom MongoDB image:
$ docker build -t custom-mongo .
Sending build context to Docker daemon 2.56kB
Step 1/4 : FROM mongo:latest
---> 81a05b728352
Step 2/4 : ENV MONGO_INITDB_ROOT_USERNAME=admin
---> Running in b0831f91f979
Removing intermediate container b0831f91f979
---> 02ae0ea46d81
Step 3/4 : ENV MONGO_INITDB_ROOT_PASSWORD=password
---> Running in 5ffe89493c6a
Removing intermediate container 5ffe89493c6a
---> 057d12cd4e58
Step 4/4 : COPY mongo-init.js /docker-entrypoint-initdb.d/
---> 37eb14b2bd41
Successfully built 37eb14b2bd41
Successfully tagged custom-mongo:latest
This command builds the Docker image using the Dockerfile in the current directory and tags it as custom-mongo.
To run the custom MongoDB container, we can use the following docker run command:
$ docker run -d --name mongodb -p 27017:27017 custom-mongo
8033f9dea3b2825f4acbe42e408a142c495cda41f0136af89eebe5435dfaf167
This command starts the MongoDB service.
In this article, we’ve explored different methods for initializing MongoDB in Docker, including using Docker Compose, shell scripts, and custom Dockerfiles.
These approaches enable automation and customization, streamlining the process of setting up databases and users during container startup.