Skip to main content

MongoDB Deployment

Installation

Ubuntu/Debian Installation

# Import MongoDB GPG key
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -

# Add MongoDB repository
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Update package database
sudo apt-get update

# Install MongoDB
sudo apt-get install -y mongodb-org

# Start MongoDB
sudo systemctl start mongod
sudo systemctl enable mongod

# Check status
sudo systemctl status mongod

CentOS/RHEL Installation

# Create repository file
sudo tee /etc/yum.repos.d/mongodb-org-7.0.repo << EOF
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-7.0.asc
EOF

# Install MongoDB
sudo yum install -y mongodb-org

# Start and enable MongoDB
sudo systemctl start mongod
sudo systemctl enable mongod

Docker Installation

# Pull MongoDB image
docker pull mongo:7.0

# Run MongoDB container
docker run --name mongodb \
-p 27017:27017 \
-v mongodb_data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-d mongo:7.0

# Run with replica set
docker run --name mongodb-rs \
-p 27017:27017 \
-v mongodb_data:/data/db \
-d mongo:7.0 \
--replSet rs0

Configuration Files

Basic mongod.conf

# /etc/mongod.conf
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
logRotate: reopen

storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 4
directoryForIndexes: true

processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid
timeZoneInfo: /usr/share/zoneinfo

net:
port: 27017
bindIp: 127.0.0.1
maxIncomingConnections: 1000

security:
authorization: enabled

operationProfiling:
slowOpThresholdMs: 100
mode: slowOp

Production mongod.conf

# Production configuration
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
logRotate: reopen
component:
accessControl:
verbosity: 0
command:
verbosity: 1

storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
commitIntervalMs: 100
wiredTiger:
engineConfig:
cacheSizeGB: 8
journalCompressor: snappy
directoryForIndexes: true
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true

processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid

net:
port: 27017
bindIp: 0.0.0.0
maxIncomingConnections: 2000
compression:
compressors: snappy,zstd

security:
authorization: enabled
keyFile: /etc/mongodb/replica-set-key
clusterAuthMode: keyFile

replication:
replSetName: "production-replica-set"

operationProfiling:
slowOpThresholdMs: 50
mode: slowOp

setParameter:
enableLocalhostAuthBypass: false
authenticationMechanisms: SCRAM-SHA-1,SCRAM-SHA-256

Docker Compose Deployments

Single Instance

# docker-compose.yml
version: '3.8'

services:
mongodb:
image: mongo:7.0
container_name: mongodb
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
MONGO_INITDB_DATABASE: myapp
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
- mongodb_config:/data/configdb
- ./mongod.conf:/etc/mongod.conf:ro
command: mongod --config /etc/mongod.conf
networks:
- mongodb-network

mongo-express:
image: mongo-express:latest
container_name: mongo-express
restart: unless-stopped
ports:
- "8081:8081"
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_ROOT_PASSWORD}
ME_CONFIG_MONGODB_SERVER: mongodb
depends_on:
- mongodb
networks:
- mongodb-network

volumes:
mongodb_data:
mongodb_config:

networks:
mongodb-network:
driver: bridge

Replica Set with Docker Compose

# docker-compose-replica.yml
version: '3.8'

services:
mongo-primary:
image: mongo:7.0
container_name: mongo-primary
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
ports:
- "27017:27017"
volumes:
- mongo-primary-data:/data/db
- ./replica-key:/etc/mongodb/replica-key:ro
command: >
mongod --replSet production-rs
--keyFile /etc/mongodb/replica-key
--bind_ip_all
networks:
- mongo-cluster

mongo-secondary1:
image: mongo:7.0
container_name: mongo-secondary1
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
ports:
- "27018:27017"
volumes:
- mongo-secondary1-data:/data/db
- ./replica-key:/etc/mongodb/replica-key:ro
command: >
mongod --replSet production-rs
--keyFile /etc/mongodb/replica-key
--bind_ip_all
networks:
- mongo-cluster

mongo-secondary2:
image: mongo:7.0
container_name: mongo-secondary2
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
ports:
- "27019:27017"
volumes:
- mongo-secondary2-data:/data/db
- ./replica-key:/etc/mongodb/replica-key:ro
command: >
mongod --replSet production-rs
--keyFile /etc/mongodb/replica-key
--bind_ip_all
networks:
- mongo-cluster

mongo-init:
image: mongo:7.0
container_name: mongo-init
restart: "no"
depends_on:
- mongo-primary
- mongo-secondary1
- mongo-secondary2
volumes:
- ./scripts/init-replica-set.js:/scripts/init-replica-set.js:ro
command: >
mongosh --host mongo-primary:27017 -u admin -p ${MONGO_ROOT_PASSWORD}
--authenticationDatabase admin
--file /scripts/init-replica-set.js
networks:
- mongo-cluster

volumes:
mongo-primary-data:
mongo-secondary1-data:
mongo-secondary2-data:

networks:
mongo-cluster:
driver: bridge

Kubernetes Deployment

MongoDB StatefulSet

# mongodb-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: database
spec:
serviceName: mongodb-service
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:7.0
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: password
volumeMounts:
- name: mongodb-data
mountPath: /data/db
- name: mongodb-config
mountPath: /etc/mongod.conf
subPath: mongod.conf
command:
- mongod
- --config
- /etc/mongod.conf
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
volumes:
- name: mongodb-config
configMap:
name: mongodb-config
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast-ssd
resources:
requests:
storage: 100Gi

MongoDB Service

# mongodb-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
namespace: database
spec:
clusterIP: None
selector:
app: mongodb
ports:
- port: 27017
targetPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-external
namespace: database
spec:
type: LoadBalancer
selector:
app: mongodb
ports:
- port: 27017
targetPort: 27017

Cloud Deployments

MongoDB Atlas Setup

# Install Atlas CLI
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update
sudo apt-get install -y mongodb-atlas-cli

# Login to Atlas
atlas auth login

# Create cluster
atlas clusters create myCluster \
--provider AWS \
--region us-east-1 \
--tier M10 \
--diskSizeGB 100 \
--backup

# Get connection string
atlas clusters connectionStrings describe myCluster

AWS DocumentDB

# Create DocumentDB cluster (using AWS CLI)
aws docdb create-db-cluster \
--db-cluster-identifier my-docdb-cluster \
--engine docdb \
--master-username docdbadmin \
--master-user-password mypassword \
--vpc-security-group-ids sg-12345678 \
--db-subnet-group-name my-docdb-subnet-group

# Create instances
aws docdb create-db-instance \
--db-instance-identifier my-docdb-instance \
--db-instance-class db.r5.large \
--engine docdb \
--db-cluster-identifier my-docdb-cluster

Security Configuration

Generate Replica Set Key

# Generate keyfile for replica set authentication
openssl rand -base64 756 > /etc/mongodb/replica-set-key
chmod 400 /etc/mongodb/replica-set-key
chown mongodb:mongodb /etc/mongodb/replica-set-key

User Creation Script

// init-users.js
use admin;

// Create root user
db.createUser({
user: "admin",
pwd: "secureAdminPassword123",
roles: [
{ role: "root", db: "admin" }
]
});

// Switch to application database
use myapp;

// Create application user
db.createUser({
user: "appUser",
pwd: "secureAppPassword123",
roles: [
{ role: "readWrite", db: "myapp" }
]
});

// Create read-only user for backups
db.createUser({
user: "backupUser",
pwd: "secureBackupPassword123",
roles: [
{ role: "backup", db: "admin" },
{ role: "clusterMonitor", db: "admin" }
]
});

Backup and Restore

Automated Backup Script

#!/bin/bash
# mongodb-backup.sh

BACKUP_DIR="/backup/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$DATE"
MONGO_URI="mongodb://backupUser:password@localhost:27017/admin"
RETENTION_DAYS=7

# Create backup directory
mkdir -p $BACKUP_PATH

# Perform backup
mongodump --uri="$MONGO_URI" --out="$BACKUP_PATH" --gzip

# Check if backup was successful
if [ $? -eq 0 ]; then
echo "Backup completed successfully: $BACKUP_PATH"

# Compress backup
cd $BACKUP_DIR
tar -czf "${DATE}.tar.gz" $DATE
rm -rf $DATE

# Remove old backups
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup compressed and old backups cleaned up"
else
echo "Backup failed"
exit 1
fi

Restore Script

#!/bin/bash
# mongodb-restore.sh

BACKUP_FILE=$1
MONGO_URI="mongodb://admin:password@localhost:27017/admin"
TEMP_DIR="/tmp/mongo-restore"

if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup-file.tar.gz>"
exit 1
fi

# Extract backup
mkdir -p $TEMP_DIR
tar -xzf $BACKUP_FILE -C $TEMP_DIR

# Find the backup directory
BACKUP_DIR=$(find $TEMP_DIR -name "*.bson" -exec dirname {} \; | head -1 | xargs dirname)

# Perform restore
mongorestore --uri="$MONGO_URI" --drop $BACKUP_DIR

# Cleanup
rm -rf $TEMP_DIR

echo "Restore completed"

Deployment Automation

Ansible Playbook

# mongodb-deployment.yml
---
- name: Deploy MongoDB
hosts: mongodb_servers
become: yes
vars:
mongodb_version: "7.0"
mongodb_data_dir: "/var/lib/mongodb"
mongodb_log_dir: "/var/log/mongodb"
replica_set_name: "production-rs"

tasks:
- name: Install MongoDB repository key
apt_key:
url: https://www.mongodb.org/static/pgp/server-{{ mongodb_version }}.asc
state: present

- name: Add MongoDB repository
apt_repository:
repo: "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/{{ mongodb_version }} multiverse"
state: present

- name: Install MongoDB
apt:
name: mongodb-org
state: present
update_cache: yes

- name: Create MongoDB directories
file:
path: "{{ item }}"
state: directory
owner: mongodb
group: mongodb
mode: '0755'
loop:
- "{{ mongodb_data_dir }}"
- "{{ mongodb_log_dir }}"
- /etc/mongodb

- name: Generate replica set key
command: openssl rand -base64 756
register: replica_key
run_once: true
delegate_to: localhost

- name: Copy replica set key
copy:
content: "{{ replica_key.stdout }}"
dest: /etc/mongodb/replica-set-key
owner: mongodb
group: mongodb
mode: '0400'

- name: Copy MongoDB configuration
template:
src: mongod.conf.j2
dest: /etc/mongod.conf
owner: root
group: root
mode: '0644'
notify: restart mongodb

- name: Start and enable MongoDB
systemd:
name: mongod
state: started
enabled: yes

handlers:
- name: restart mongodb
systemd:
name: mongod
state: restarted

Terraform Configuration

# mongodb-infrastructure.tf
resource "aws_instance" "mongodb" {
count = 3
ami = var.ubuntu_ami
instance_type = "t3.large"
key_name = var.key_name
security_groups = [aws_security_group.mongodb.name]

root_block_device {
volume_type = "gp3"
volume_size = 100
encrypted = true
}

user_data = base64encode(templatefile("mongodb-init.sh", {
mongodb_version = "7.0"
replica_set = "production-rs"
}))

tags = {
Name = "mongodb-${count.index + 1}"
Role = "database"
}
}

resource "aws_security_group" "mongodb" {
name_prefix = "mongodb-"

ingress {
from_port = 27017
to_port = 27017
protocol = "tcp"
cidr_blocks = [var.vpc_cidr]
}

ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.admin_cidr]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

Health Checks and Monitoring

Systemd Health Check

# /etc/systemd/system/mongodb-health.service
[Unit]
Description=MongoDB Health Check
After=mongod.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mongodb-health-check.sh
User=mongodb

# /etc/systemd/system/mongodb-health.timer
[Unit]
Description=Run MongoDB Health Check
Requires=mongodb-health.service

[Timer]
OnCalendar=*:0/5 # Every 5 minutes
Persistent=true

[Install]
WantedBy=timers.target

Production Deployment Checklist

## MongoDB Production Deployment Checklist

### Security
- [ ] Enable authentication
- [ ] Create application-specific users with minimal privileges
- [ ] Configure replica set keyfile
- [ ] Enable SSL/TLS encryption
- [ ] Configure firewall rules
- [ ] Disable unnecessary services
- [ ] Set up auditing

### Performance
- [ ] Configure appropriate WiredTiger cache size
- [ ] Create necessary indexes
- [ ] Enable query profiling
- [ ] Configure connection pooling
- [ ] Set up monitoring and alerting
- [ ] Optimize storage configuration

### High Availability
- [ ] Deploy replica set with at least 3 members
- [ ] Configure proper read preferences
- [ ] Set up automated failover
- [ ] Test disaster recovery procedures
- [ ] Configure backup automation

### Monitoring
- [ ] Set up MongoDB monitoring (Ops Manager/Atlas/Prometheus)
- [ ] Configure log rotation
- [ ] Set up alerting for critical metrics
- [ ] Monitor replication lag
- [ ] Track performance metrics

### Maintenance
- [ ] Schedule regular backups
- [ ] Plan for MongoDB version upgrades
- [ ] Document runbooks and procedures
- [ ] Set up log aggregation
- [ ] Configure capacity planning alerts