Deploy a MongoDB Cluster with Docker
Tags: tutorial, mongodb, docker, linux
Published: 2023-12-27 13:11:21

[Percona Backup for MongoDB](https://docs.percona.com/percona-backup-mongodb/index.html) (PBM) is an open-source distributed and low-impact solution for consistent backups of MongoDB sharded clusters and replica sets.

PBM doesn’t work on standalone MongoDB instances, as it requires an [oplog](https://docs.percona.com/percona-backup-mongodb/reference/glossary.html#oplog) (operations log) to guarantee backup consistency. Oplog is only available on nodes with replication enabled.

You can deploy Percona Backup for MongoDB for testing purposes on a single-node replica set. Follow [this guide](https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/) from the MongoDB documentation to learn how to convert a standalone to a replica set.

You can also use Docker to deploy a MongoDB cluster on your personal computer, as well as set up the storage and run PBM. Using Docker can be useful for testing PBM in a development environment before running it in production.

Through this series of blog posts, you will learn how to configure a development environment for PBM, starting with the creation of a three-node replica set, one node set as primary and two secondary nodes. Continuing with the configuration of MinIO to store the backups of your databases, and finally configuring PBM and testing it. 

This series includes the following articles:
1. Deploy a MongoDB Cluster with Docker
2. [Object Storage with MinIO](https://dev.to/mattdark/object-storage-with-minio-in-docker-2mig)
3. [Running Percona Backup for MongoDB With Docker](https://dev.to/mattdark/running-percona-backup-for-mongodb-with-docker-ep4)

For deploying a MongoDB cluster, I've followed the instructions from [this tutorial](https://www.mongodb.com/compatibility/deploying-a-mongodb-cluster-with-docker), but I will explain the general process to get a cluster with replication enabled and ready to use.

## Deploy a MongoDB Cluster
![MongoDB Cluster](https://gitlab.com/mattdark/blog-posts-assets/-/raw/master/pbm-docker/mongodb-cluster.jpg)

You can deploy MongoDB clusters in a number of ways
* Install MongoDB on your computer and [deploy a replica set](https://docs.mongodb.com/manual/replication/)
* Use Docker to run your cluster
* Deploy a highly available cluster on Kubernetes

For the purpose of this series, we’re going to work with Docker because it’s easy and a great way to try out the backup methods without additional hardware. These are the steps for creating a MongoDB cluster with Docker:

1. Create a Docker network.
2. Start three instances of MongoDB.
3. Initiate the Replica Set.

### Create a Docker Network
First, create a Docker network by running the following command:

```
$ docker network create mongodbCluster
```

if the network has been created, you can get its details by running the following command:

```
$ docker network inspect mongodbCluster
```

The output of the above command looks like this

```
[
    {
        "Name": "mongodbCluster",
        "Id": "ebde001d9f02012f803a5914a3b450f6e6092a972ccfd513afb61399cbdca2a4",
        "Created": "2023-02-23T16:02:13.629671156Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

```

### Start MongoDB Instances
Create your primary node and add it to the network you created before:

```
$ docker run -d -p 27017:27017 --name mongo1 --network mongodbCluster mongo:6 mongod --replSet myReplicaSet --bind_ip localhost,mongo1
```

The parameters in the above command are:
* `-d`. Running the container in detached mode
* `-p`. The port in the host machine that will receive and redirect all the requests to the port in the container
* `--name`. Name of the container
* `--network`. Name of the network to use
* `mongo:6`. Name of the base image used for creating the container

The following command will be run in the initialized container:

```
mongod --replSet myReplicaSet --bind_ip localhost,mongo1
```

Where:

* The `--replSet` option is used to set a name (`myReplicaSet`) for your replica set
* The `--bind_ip` option is used to ensure that MongoDB listens for connections from applications on configured addresses. In this case, the `mongod` instance binds to both the localhost and the hostname (`mongo1`)

Once the primary node is created, you must create the secondary nodes of your replica set:

```
$ docker run -d -p 27018:27017 --name mongo2 --network mongodbCluster mongo:6 mongod --replSet myReplicaSet --bind_ip localhost,mongo2
```

```
$ docker run -d -p 27019:27017 --name mongo3 --network mongodbCluster mongo:6 mongod --replSet myReplicaSet --bind_ip localhost,mongo3
```

### Initiate the Replica Set
After your cluster is created, you must initiate the replica set. Run the `rs.initiate()` method in the primary node of your cluster:

```
$ docker exec -it mongo1 mongosh --eval "rs.initiate({
 _id: \"myReplicaSet\",
 members: [
   {_id: 0, host: \"mongo1\"},
   {_id: 1, host: \"mongo2\"},
   {_id: 2, host: \"mongo3\"}
 ]
})"
```

If the replica set was initiated, you will get the following output:

```
{ ok: 1 }
```

Check the status of your replica set by running:

```
docker exec -it mongo1 mongosh --eval "rs.status()"
```

### Authentication
For authenticating on your MongoDB cluster, create a user with [userAdminAnyDatabase](https://www.mongodb.com/docs/manual/reference/built-in-roles/#mongodb-authrole-userAdminAnyDatabase) and [readWriteAnyDatabase](https://www.mongodb.com/docs/manual/reference/built-in-roles/#mongodb-authrole-readWriteAnyDatabase) roles, following the instructions [here](https://www.mongodb.com/docs/manual/tutorial/configure-scram-client-authentication/). 

Log into your MongoDB server:

```
$ docker exec -it mongo1 mongosh
```

Switch to the adming database

```
$ use admin
```

And add a new user:

```
db.createUser(
 {
   user: "myUserAdmin",
   pwd: passwordPrompt(), // or cleartext password
   roles: [
     { role: "userAdminAnyDatabase", db: "admin" },
     { role: "readWriteAnyDatabase", db: "admin" }
   ]
 }
)
```

Replace `myUserAdmin` with your desired username. With `passwordPrompt()` you will be asked to write the password you want to assign, or you can write the value there instead of calling that method.

Once the user is created, you can log in from the command line:

```
$ mongosh --username myUserAdmin --password --host mongo1
```

It will ask you to type in your password. If you’re accessing from outside the cluster, you must replace mongo1 with the IP address of the primary node of your cluster.

Or you can pass a connection string:

```
$ mongosh “mongodb://myUserAdmin:password@localhost/mydb”
```

Replacing `password`, `localhost`, and `mydb` with your authentication details.

## Conclusion
Through this blog post, you learned to set up a MongoDB cluster with replication enabled using Docker. This is the first part of a series of blog posts that will guide you through the steps for configuring Percona Backup for MongoDB in a development environment to try this tool before using it in production.

---

[![Support me on Buy Me A Coffee](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzx9uenqvwqv1vp8ub5d.png)](https://buymeacoffee.com/letstalkoss)