MongoDB composed
Tags: docker, mongodb
Published: 2023-06-13 00:53:11

### Introduction:
This post provides a ready-to-use `Docker Compose` based configuration that allows you to effortlessly set up a `MongoDB single node replica set` with a reliable `healthcheck` and a `Web GUI` of mongo-express.

### Prerequisites

- [Basic knowledge of Docker Compose](https://docs.docker.com/compose/)
- [Install Docker Compose](https://docs.docker.com/compose/install/)
- [Basic knowledge of MongoDB](https://www.mongodb.com/docs/)

### Configuration

#### `docker-compose.yml`

```yml
version: '3.9'

services:
  mongo:
    container_name: mongo
    image: mongo:${MONGO_VERSION} # https://hub.docker.com/_/mongo
    entrypoint:
      - bash
      - -c
      - |
        if [ ! -f ${MONGO_REPLICA_SET_KEY_FILE} ]; then
          echo "generating replica set key file ..."
          openssl rand -base64 756 > ${MONGO_REPLICA_SET_KEY_FILE}
          chmod 600 ${MONGO_REPLICA_SET_KEY_FILE}
          chown 999:999 ${MONGO_REPLICA_SET_KEY_FILE}
        fi
        exec docker-entrypoint.sh $$@
    command: "--bind_ip_all --replSet ${MONGO_REPLICA_SET_NAME} --keyFile ${MONGO_REPLICA_SET_KEY_FILE}"
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
    ports:
      - 27017:27017
    healthcheck:
      test: test $$(echo "rs.initiate().ok || rs.status().ok" | mongo -u $${MONGO_INITDB_ROOT_USERNAME} -p $${MONGO_INITDB_ROOT_PASSWORD} --quiet) -eq 1
      start_period: 30s
    restart: unless-stopped

  mongo-gui:
    container_name: mongo-gui
    image: mongo-express:${MONGO_GUI_VERSION} # https://hub.docker.com/_/mongo-express
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_USERNAME}
      ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_PASSWORD}
      ME_CONFIG_MONGODB_SERVER: mongo
      ME_CONFIG_MONGODB_ENABLE_ADMIN: true
    ports:
      - 8081:8081
    depends_on:
      mongo:
        condition: service_healthy
    restart: unless-stopped
```

#### `.env`

```bash
MONGO_VERSION=5.0.18 # pick your version from https://hub.docker.com/_/mongo/tags
MONGO_USERNAME=root
MONGO_PASSWORD=root
MONGO_REPLICA_SET_NAME=rs0
MONGO_REPLICA_SET_KEY_FILE=/opt/rs.key
MONGO_GUI_VERSION=0.54.0 # change to "latest" after a stable release, currently on 1.0.0-alpha.X
```

#### connection string

```bash
# directConnection=true is a must for the local topology - see https://www.mongodb.com/docs/drivers/node/current/fundamentals/connection/connect/#direct-connection, https://jira.mongodb.org/browse/NODE-2966
MONGODB_URL=mongodb://root:root@localhost:27017?replicaSet=rs0&directConnection=true
```

#### commands

```bash
# start
docker compose --project-name composed-mongodb up --detach

# stop
docker compose --project-name composed-mongodb stop

# clean
docker compose --project-name composed-mongodb down --volumes --remove-orphans
```

### verify

Open the browser and navigate to [http://localhost:8081/](http://localhost:8081/), you should see the following:

![Mongo Express](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/es980wnyfoc1jkvdnovt.jpg)

### Resources:
- https://www.fatalerrors.org/a/docker-compose-builds-mongodb-replica-set-records.html
- https://stackoverflow.com/questions/61486024/mongo-container-with-a-replica-set-with-only-one-node-in-docker-compose
- https://zgadzaj.com/development/docker/docker-compose/turning-standalone-mongodb-server-into-a-replica-set-with-docker-compose
- https://blog.tericcabrel.com/mongodb-replica-set-docker-compose/
- https://flowygo.com/en/blog/mongodb-and-docker-how-to-create-and-configure-a-replica-set/
- https://github.com/docker-library/mongo/issues/501
- https://gist.github.com/crapthings/71fb6156a8e9b31a2fa7946ebd7c4edc
- https://github.com/docker-library/mongo/issues/475