IMPORTANT: There is an issue with the official MongoDB Compass client. When you try to connect to a ReplicaSet, it first correctly translates the MongoDB connection string (DNS) to localhost:PORT. However, once it reads the member hostnames (like in this script), it will attempt to connect to those hosts instead!
Usualy, the script would look like this:
rs.initiate(
{
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" },
]
}
)
But this won't work because mongo1 would only be reachable on the Docker network, not from your host. Therefore, we need to use the same address as our Docker setup for the 'outside' world.
rs.initiate(
{
_id: "rs0",
members: [
{ _id: 0, host: "localhost:45201" }
]
}
)
Using this approach will allow Compass to translate localhost and connect without the need to update the host file or any other configuration.
Use the same script to check if any ReplicaSet already exists instead of getting error code 1.
try {
if (!rs.status().ok) {
rs.initiate(
{
_id: "rs0",
members: [
{ _id: 0, host: "localhost:45201" }
]
}
);
}
} catch (e) {
// Do nothing if some ReplicaSet already exists.
}
This will prepare a MongoDB instance to become a ReplicaSet, but it has to be initiated while the service is running.
Init command example: mongosh -u root -p root --port 45201 /mongo_init/rs-initiate.js
FROM mongo:latest
WORKDIR /mongo_init
# Generate new ReplicaSet keyfile
RUN openssl rand -base64 756 > replicaset_keyfile
RUN chmod 0400 replicaset_keyfile
RUN chown 999:999 replicaset_keyfile
# Prepare MongoDB init script to be used when server starts
COPY ./docker/rs-initiate.js .
RUN chmod 0400 rs-initiate.js
RUN chown 999:999 rs-initiate.js
# Run the MongoDB server with the specified options
CMD ["mongod", "--port", "45201", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "replicaset_keyfile"]
services:
mongodb:
build:
context: .
dockerfile: docker/mongo.Dockerfile
ports:
- "45201:45201"
volumes:
- mongodb:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root
volumes:
mongodb:
- Create Dockerfile, compose.yaml and rs-initiate.js file
- Set paths in Dockerfile and compose so it points to the correct file locations on your host.
# Spin up container
docker compose up -d
# Init ReplicaSet
docker compose exec mongodb mongosh -u root -p root --port 45201 /mongo_init/rs-initiate.js
Put this to Makefile or whatever