MongoDB single instance replicaset with Docker
Setting up a MongoDB Docker instance that supports oplog tailing and change streams for development
MongoDB single instance replicaset with Docker
MongoDB replicasets are required for oplog tailing and subscribing to change stream events. When running a single instance with these features on Docker, finding the correct configuration can be challenging. After working through this setup, I’m sharing a working solution that enables both features in a development environment.
FROM mongo:latest
ARG MONGO_INITDB_ROOT_USERNAME
ENV MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
ARG MONGO_INITDB_ROOT_PASSWORD
ENV MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
ARG MONGO_KEYFILE_KEY
ARG CONTAINER_HOSTNAME
ENV CONTAINER_HOSTNAME=${CONTAINER_HOSTNAME}
ARG PORT
ENV PORT=${PORT}
ENV HOST_PORT="${CONTAINER_HOSTNAME}:${PORT}"
USER root
RUN echo ${MONGO_KEYFILE_KEY} > "/tmp/replica.key"
RUN chmod 400 /tmp/replica.key
RUN chown 999:999 /tmp/replica.key
EXPOSE ${PORT}
HEALTHCHECK --interval=5s --timeout=30s --start-period=5s --retries=30 \
CMD echo "rs.initiate({_id: 'rs0', members: [{_id: 1, host: \"${HOST_PORT}\"}]}) || rs.status().ok" | \
mongosh -u ${MONGO_INITDB_ROOT_USERNAME} -p ${MONGO_INITDB_ROOT_PASSWORD} --port ${PORT} --quiet
CMD ["--replSet", "rs0", "--bind_ip_all", "--keyFile", "/tmp/replica.key", "--port=$PORT"]
The Dockerfile uses build arguments and environment variables to configure the root username and password, custom keyfile key, hostname, and port.
Environment Configuration
For local testing, create a .env file with the following values:
MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=your-own-very-secret-password
MONGO_KEYFILE_KEY='*********'
CONTAINER_HOSTNAME=mongodb
PORT=27017
Generating the Keyfile
Generate the required authentication key using OpenSSL:
openssl rand -base64 756
Building the Docker Image
Build the image using the environment variables:
docker build -t mongo_rs0 \
--build-arg MONGO_INITDB_ROOT_USERNAME="$MONGO_INITDB_ROOT_USERNAME" \
--build-arg MONGO_INITDB_ROOT_PASSWORD="$MONGO_INITDB_ROOT_PASSWORD" \
--build-arg MONGO_KEYFILE_KEY="$MONGO_KEYFILE_KEY" \
--build-arg CONTAINER_HOSTNAME="$CONTAINER_HOSTNAME" \
--build-arg PORT="$PORT" .
Alternatively, generate the build command automatically from the .env file:
while IFS= read -r line; do
arg=$(echo $line | cut -d '=' -f 1)
val=$(echo $line | cut -d '=' -f 2)
build_args+=" --build-arg $arg=$val"
done < .env
docker build $build_args .
Running the Container
Start the container using the environment file:
docker run --name mongodb --env-file .env mongo_rs0
Integration with CapRover
This configuration works seamlessly with CapRover, which automatically uses environment variables as both build arguments and container environment variables.