Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
November 7, 2022 04:50 pm GMT

Dockerizing a MongoDB Replica Set With TLS/SSL

Introduction

The goal of this guide is to create a local SSL-enabled MongoDB Replica Set using docker-compose.

TL;DR: Here is a demo repository. Note that to run locally you will have to create your own ssl/ directory and populate the certificate data.

Prerequisites

Docker is the only pre-requisite, but if you want to connect to the mongo shell locally (recommended) you will need MongoDB.

File Structure

Here is the file structure used in this tutorial:

.db/config/ mongodb.confssl/ ca.pem server.pemdocker-compose.ymlinit.shrun.shwait-for-mongo.sh

.db/*

This is the database path for the mongod configuration and should be generated automatically by docker-compose.

ssl/*

The files ssl/ca.pem and ssl/server.pem are the TLS CA file and TLS certificate key file, respectively. The data in the ssl/ directory is used by the configuration file to initialize a MongoDB server with SSL enabled. This directory will be volumized on the Docker container for the primary replicant.

This tutorial assumes prior knowledge of TLS/SSL as well as access to valid certificates. For more information on generating certificates using openssl, see this guide.

config/mongodb.conf

This is the configuration file used to configure the mongod instance at startup and will be be volumized on the Docker container for the primary replicant:

net:  ssl:    mode: requireSSL    PEMKeyFile: "/data/ssl/server.pem"    CAFile: "/data/ssl/ca.pem"storage:  dbPath: "/data/db"net:  bindIp: 127.0.0.1  port: 27017

init.sh

This shell file is used to initialize the replica set and will be ran in the docker container for the primary node (i.e. mongo1, defined in the "docker-compose.yml" section).

#!/bin/bashmongosh --tls \  --tlsCAFile /data/ssl/ca.pem \  --tlsCertificateKeyFile /data/ssl/server.pem <<EOFvar config = {    "_id": "dbrs",    "version": 1,    "members": [        {            "_id": 1,            "host": "mongo1:27017",            "priority": 3        }    ]};rs.initiate(config, { force: true });rs.status();var config = {    "_id": "dbrs",    "version": 1,    "members": [        {            "_id": 2,            "host": "mongo2:27017",            "priority": 2        },        {            "_id": 3,            "host": "mongo3:27017",            "priority": 1        }    ]};rs.initiate(config, { force: true });rs.status();EOF

docker-compose.yml

In our docker-compose file, we create three nodes: mongo1 (primary), mongo2, and mongo3. These replicant containers use the bridge network mongo_network.

version: '3'networks:  mongo_network:    driver: bridgeservices:  mongo1:    hostname: mongo1    image: mongo    ports:      - 27017:27017    restart: always    entrypoint: [ "/usr/bin/mongod", "--config", "/data/config/ssl.conf", "--bind_ip_all", "--replSet", "dbrs" ]    networks:      - mongo_network    volumes:      - ./.db/mongo1:/data/db      - ./wait-for-mongodb.sh:/scripts/wait-for-mongodb.sh      - ./init.sh:/scripts/init.sh      - ./ssl:/data/ssl      - ./config:/data/config    links:      - mongo2      - mongo3  mongo2:    hostname: mongo2    image: mongo    ports:      - 27018:27017    restart: always    entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "dbrs" ]    networks:      - mongo_network    volumes:      - ./.db/mongo2:/data/db      - ./wait-for-mongodb.sh:/scripts/wait-for-mongodb.sh  mongo3:    hostname: mongo3    image: mongo    ports:      - 27019:27017    restart: always    entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "dbrs" ]    networks:      - mongo_network    volumes:      - ./.db/mongo3:/data/db      - ./wait-for-mongodb.sh:/scripts/wait-for-mongodb.sh

Before composing, it is recommended to update the /etc/hosts file to include the replicant mappings:

# Replica set mappings127.0.0.1 mongo1127.0.0.1 mongo2127.0.0.1 mongo3

wait-for-mongo.sh

This script will wait for a mongo server to come up

#!/bin/bashNAME=$1OPTS=$2while [ -z `mongosh --eval 'db.runCommand("ping").ok' --quiet --host $OPTS 2>/dev/null` ]; do    echo "Waiting for MongoDB $NAME to start..."    sleep 1doneecho "MongoDB $NAME is up and running"

run.sh

run.sh will (1) start the replicants, (2) wait for the replicants to come up, and (3) define primary and secondary replicants on mongo1.

#!/bin/bashset -e# remove volumesrm -rf .db# drop existing containersdocker compose -f "docker-compose.yml" down# prune containersdocker system prune --forcedocker-compose -f "docker-compose.yml" up -d \    --remove-orphans \    --force-recreate \    --build mongo1docker-compose -f "docker-compose.yml" up -d \    --remove-orphans \    --force-recreate \    --build mongo2docker-compose -f "docker-compose.yml" up -d \    --remove-orphans \    --force-recreate \    --build mongo3docker-compose -f "docker-compose.yml" exec -T mongo3 /scripts/wait-for-mongodb.sh "mongo3:27017"docker-compose -f "docker-compose.yml" exec -T mongo2 /scripts/wait-for-mongodb.sh "mongo2:27017"M1_OPTS="--tls --tlsCAFile /data/ssl/ca.pem --tlsCertificateKeyFile /data/ssl/server.pem --tlsAllowInvalidCertificates"docker-compose -f "docker-compose.yml" exec -T mongo1 /scripts/wait-for-mongodb.sh "mongo1:27017" "$M1_OPTS"echo "Creating replica set..."docker-compose -f "docker-compose.yml" exec -T mongo1 /scripts/init.sh

Putting everything together, we run the above shell script and then test our setup by opening a mongo shell:

mongosh --tls --tlsCAFile <path-to-ca-file> --tlsCertificateKeyFile <path-to-client-file>

Original Link: https://dev.to/prestonvasquez/dockerizing-a-mongodb-replica-set-with-tlsssl-20e2

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To