Quick start on how to containerize MongoDB Replica Set on your machine.
In about 5 minutes, the 3-Node Replica Set will be running on your machine without any prior experience with container platforms or databases.
What is the purpose of a Replica Set on a single machine?
Initializing a Replica Set on a single machine is necessary to enable certain MongoDB features such as Changestreams for real-time applications and Transactions for ACID-compliant database operations.
Prerequisites
- Editor of your choice, I will be using Visual Studio Code
- Container platform with Compose support, I will demonstrate using both Docker and Podman
Getting started
- Your directory should look something like this:
project
├── compose.yml
└── .env
- Copy and paste the compose.yml:
services:
mongo_1:
container_name: mongo_1
hostname: mongo_1
image: mongo:latest
command: >
bash -c "
echo 'Starting without auth for initial setup...'
if [ ! -f /shared/setup_completed ]; then
echo 'Running without auth for replica set initialization'
mongod --replSet rs0 --bind_ip_all --port 27017 &
while [ ! -f /shared/setup_completed ]; do
sleep 1
done
echo 'Setup completed, restarting with auth...'
pkill mongod
sleep 2
fi
echo 'Starting with auth...'
mongod --replSet rs0 --bind_ip_all --port 27017 --keyFile /shared/mongodb-keyfile --auth
"
volumes:
- mongo_1_data:/data/db
- mongo_1_config:/data/configdb
- mongo_keyfile:/shared
restart: always
networks:
- mongo_network
ports:
- "27017:27017"
mongo_2:
container_name: mongo_2
hostname: mongo_2
image: mongo:latest
command: >
bash -c "
echo 'Starting without auth for initial setup...'
if [ ! -f /shared/setup_completed ]; then
echo 'Running without auth for replica set initialization'
mongod --replSet rs0 --bind_ip_all --port 27018 &
while [ ! -f /shared/setup_completed ]; do
sleep 1
done
echo 'Setup completed, restarting with auth...'
pkill mongod
sleep 2
fi
echo 'Starting with auth...'
mongod --replSet rs0 --bind_ip_all --port 27018 --keyFile /shared/mongodb-keyfile --auth
"
volumes:
- mongo_2_data:/data/db
- mongo_2_config:/data/configdb
- mongo_keyfile:/shared
restart: always
networks:
- mongo_network
ports:
- "27018:27018"
mongo_3:
container_name: mongo_3
hostname: mongo_3
image: mongo:latest
command: >
bash -c "
echo 'Starting without auth for initial setup...'
if [ ! -f /shared/setup_completed ]; then
echo 'Running without auth for replica set initialization'
mongod --replSet rs0 --bind_ip_all --port 27019 &
while [ ! -f /shared/setup_completed ]; do
sleep 1
done
echo 'Setup completed, restarting with auth...'
pkill mongod
sleep 2
fi
echo 'Starting with auth...'
mongod --replSet rs0 --bind_ip_all --port 27019 --keyFile /shared/mongodb-keyfile --auth
"
volumes:
- mongo_3_data:/data/db
- mongo_3_config:/data/configdb
- mongo_keyfile:/shared
restart: always
networks:
- mongo_network
ports:
- "27019:27019"
mongo_setup:
container_name: mongo_setup
image: mongo:latest
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
command: >
bash -c "
if [ -f /shared/setup_completed ]; then
echo 'Cluster setup already completed, skipping'
exit 0
fi
echo 'Generating keyfile...' &&
if [ ! -f /shared/mongodb-keyfile ]; then
openssl rand -base64 756 > /shared/mongodb-keyfile &&
chmod 600 /shared/mongodb-keyfile &&
chown 999:999 /shared/mongodb-keyfile &&
echo 'Keyfile generated successfully'
else
echo 'Keyfile already exists, skipping generation'
fi &&
echo 'Waiting for node startup...' &&
sleep 5 &&
echo 'Initializing replica set...' &&
mongosh --host mongo_1 --port 27017 --eval '
try {
rs.initiate({
_id: "rs0",
members: [
{_id: 0, host: "mongo_1:27017", priority: 1},
{_id: 1, host: "mongo_2:27018", priority: 0.5},
{_id: 2, host: "mongo_3:27019", priority: 0.5}
]
});
print("Replica set initialized successfully");
} catch (e) {
print("Replica set initialization failed or already exists: " + e);
}
' &&
echo 'Waiting for primary election...' &&
sleep 20 &&
echo 'Creating admin user...' &&
mongosh --host mongo_1 --port 27017 --eval '
try {
db = db.getSiblingDB("admin");
db.createUser({
user: "'$$MONGO_INITDB_ROOT_USERNAME'",
pwd: "'$$MONGO_INITDB_ROOT_PASSWORD'",
roles: [{role: "root", db: "admin"}]
});
print("Admin user created successfully");
} catch (e) {
print("User creation failed: " + e);
throw e;
}
' &&
touch /shared/setup_completed &&
echo 'Cluster setup completed successfully!'
"
volumes:
- mongo_setup_data:/data/db
- mongo_setup_config:/data/configdb
- mongo_keyfile:/shared
restart: "no"
networks:
- mongo_network
mongo_express:
container_name: mongo_express
image: mongo-express:latest
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_INITDB_ROOT_USERNAME}
- ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
- ME_CONFIG_MONGODB_URL=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo_1:27017,mongo_2:27018,mongo_3:27019/?replicaSet=rs0
- ME_CONFIG_BASICAUTH_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
- ME_CONFIG_BASICAUTH_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
restart: always
networks:
- mongo_network
ports:
- "8081:8081"
volumes:
mongo_1_data:
mongo_2_data:
mongo_3_data:
mongo_setup_data:
mongo_1_config:
mongo_2_config:
mongo_3_config:
mongo_setup_config:
mongo_keyfile:
networks:
mongo_network:
driver: bridge
- Set your admin username and password in
.env
:
MONGO_INITDB_ROOT_USERNAME="root"
MONGO_INITDB_ROOT_PASSWORD="pass"
Run the Compose setup in your project directory
Docker:
docker compose up -d
- Podman:
podman compose up -d
Wait about 45 seconds, then run the setup logs
Docker:
docker logs mongo_setup
- Podman:
podman logs mongo_setup
- If everything went right the output should look like this:
Generating keyfile...
Keyfile generated successfully
Waiting for node startup...
Initializing replica set...
Replica set initialized successfully
Waiting for primary election...
Creating admin user...
Admin user created successfully
Cluster setup completed successfully!
The final step is to map hosts 127.0.0.1 to mongo_1, mongo_2 and mongo_3
Windows Powershell:
Start-Process powershell.exe -Verb RunAs -ArgumentList '-NoProfile', '-Command', 'Add-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Value "`n127.0.0.1 mongo_1 mongo_2 mongo_3"'
- Mac/Linux Zsh/Bash:
echo "127.0.0.1 mongo_1 mongo_2 mongo_3" | sudo tee -a /etc/hosts > /dev/null
Access your MongoDB Replica Set
Open your browser on
http://localhost:8081/
and login with your.env
credentialsTo connect via MongoDB Compass or drivers, use this connection string to enable Replica Set connectivity with automatic failover. (Be sure to replace
"root"
and"pass"
with your.env
credentials):
mongodb://root:pass@127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/?replicaSet=rs0
Top comments (1)
bad guide doenst work D:
down vote