Configure a production-grade MongoDB 8.0 sharded cluster with replica sets, config servers, and mongos routers for horizontal scaling. This tutorial covers automated chunk balancing, high availability, and enterprise-ready deployment patterns.
Prerequisites
- At least 9 servers (3 config, 6 shard members)
- Minimum 4GB RAM per server
- Network connectivity between all nodes
- Root or sudo access on all servers
What this solves
MongoDB sharding distributes data across multiple servers to handle large datasets and high-throughput operations that exceed single-server capacity. A properly configured sharded cluster provides horizontal scaling, automatic failover through replica sets, and transparent data distribution.
Step-by-step configuration
Update system packages and install MongoDB 8.0
Start by updating your package manager and installing MongoDB 8.0 on all cluster nodes.
sudo apt update && sudo apt upgrade -y
wget -qO - https://www.mongodb.org/static/pgp/server-8.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt update
sudo apt install -y mongodb-org
Configure config server replica set
Config servers store cluster metadata and shard configuration. Set up three config servers for high availability on separate nodes.
# Config Server Configuration
storage:
dbPath: /var/lib/mongodb-config
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod-config.log
net:
port: 27019
bindIp: 0.0.0.0
processManagement:
fork: true
pidFilePath: /var/run/mongod-config.pid
timeZoneInfo: /usr/share/zoneinfo
sharding:
clusterRole: configsvr
replication:
replSetName: configReplSet
security:
authorization: enabled
keyFile: /etc/mongodb-keyfile
Create shared authentication keyfile
Generate a keyfile for internal cluster authentication and distribute it to all cluster nodes with proper permissions.
sudo mkdir -p /etc/mongodb
sudo openssl rand -base64 756 | sudo tee /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile
Create data directories and start config servers
Create dedicated data directories for config servers and start the service on all three config server nodes.
sudo mkdir -p /var/lib/mongodb-config
sudo chown mongodb:mongodb /var/lib/mongodb-config
sudo chmod 755 /var/lib/mongodb-config
sudo mongod --config /etc/mongod-config.conf
Initialize config server replica set
Connect to one config server and initialize the replica set with all three config server members.
mongosh --port 27019
rs.initiate({
_id: "configReplSet",
configsvr: true,
members: [
{ _id: 0, host: "203.0.113.10:27019" },
{ _id: 1, host: "203.0.113.11:27019" },
{ _id: 2, host: "203.0.113.12:27019" }
]
})
rs.status()
Create admin user on config servers
Create an administrative user with cluster management privileges on the config server replica set.
use admin
db.createUser({
user: "clusterAdmin",
pwd: "SecureClusterPass123!",
roles: [
{ role: "clusterAdmin", db: "admin" },
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
})
Configure shard replica sets
Set up replica sets for each shard. Create configuration files for the first shard replica set members.
# Shard 1 Configuration
storage:
dbPath: /var/lib/mongodb-shard1
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod-shard1.log
net:
port: 27018
bindIp: 0.0.0.0
processManagement:
fork: true
pidFilePath: /var/run/mongod-shard1.pid
timeZoneInfo: /usr/share/zoneinfo
sharding:
clusterRole: shardsvr
replication:
replSetName: shard1ReplSet
security:
authorization: enabled
keyFile: /etc/mongodb-keyfile
Start shard replica set members
Create data directories and start MongoDB instances for the first shard replica set on three separate nodes.
sudo mkdir -p /var/lib/mongodb-shard1
sudo chown mongodb:mongodb /var/lib/mongodb-shard1
sudo chmod 755 /var/lib/mongodb-shard1
sudo mongod --config /etc/mongod-shard1.conf
Initialize shard replica sets
Connect to the primary shard node and initialize the shard replica set with all members.
mongosh --port 27018
rs.initiate({
_id: "shard1ReplSet",
members: [
{ _id: 0, host: "203.0.113.20:27018" },
{ _id: 1, host: "203.0.113.21:27018" },
{ _id: 2, host: "203.0.113.22:27018" }
]
})
rs.status()
Configure mongos routers
Set up mongos instances that route queries to appropriate shards. Mongos instances are stateless query routers.
# Mongos Router Configuration
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongos.log
net:
port: 27017
bindIp: 0.0.0.0
processManagement:
fork: true
pidFilePath: /var/run/mongos.pid
timeZoneInfo: /usr/share/zoneinfo
sharding:
configDB: configReplSet/203.0.113.10:27019,203.0.113.11:27019,203.0.113.12:27019
security:
keyFile: /etc/mongodb-keyfile
Start mongos routers
Start mongos instances on multiple nodes for high availability and load distribution.
sudo mongos --config /etc/mongos.conf
Add shards to cluster
Connect to mongos and add the configured shard replica sets to the cluster.
mongosh --port 27017 -u clusterAdmin -p SecureClusterPass123! --authenticationDatabase admin
sh.addShard("shard1ReplSet/203.0.113.20:27018,203.0.113.21:27018,203.0.113.22:27018")
sh.addShard("shard2ReplSet/203.0.113.30:27018,203.0.113.31:27018,203.0.113.32:27018")
sh.status()
Enable sharding for databases and collections
Enable sharding on target databases and configure shard keys for optimal data distribution.
sh.enableSharding("myapp")
sh.shardCollection("myapp.users", { "user_id": 1 })
sh.shardCollection("myapp.orders", { "order_date": 1, "customer_id": 1 })
Configure chunk balancing settings
Customize the balancer settings for optimal performance and configure balancing windows if needed.
use config
db.settings.updateOne(
{ _id: "balancer" },
{ $set: { activeWindow : { start : "01:00", stop : "05:00" } } },
{ upsert: true }
)
sh.setBalancerState(true)
sh.getBalancerState()
Create systemd service files
Create systemd service files for automatic startup and management of MongoDB components.
[Unit]
Description=MongoDB Config Server
After=network.target
[Service]
Type=forking
User=mongodb
Group=mongodb
ExecStart=/usr/bin/mongod --config /etc/mongod-config.conf
PIDFile=/var/run/mongod-config.pid
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable mongod-config
sudo systemctl enable mongod-shard1
sudo systemctl enable mongos
Verify your setup
Check cluster status and verify proper shard distribution.
mongosh --port 27017 -u clusterAdmin -p SecureClusterPass123! --authenticationDatabase admin
sh.status()
use myapp
db.users.getShardDistribution()
db.stats()
For more advanced database configuration, check out our MongoDB 8.0 authentication and SSL encryption tutorial or learn about connection pooling strategies.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Config server won't start | Incorrect keyfile permissions | sudo chown mongodb:mongodb /etc/mongodb-keyfile && sudo chmod 400 /etc/mongodb-keyfile |
| Shard addition fails | Replica set not initialized | Connect to shard and run rs.status() to verify replica set health |
| Balancer not running | Balancer disabled or window restriction | sh.setBalancerState(true) and check db.settings.find({_id:"balancer"}) |
| Authentication failures | Keyfile mismatch between nodes | Ensure identical keyfile content on all cluster members |
| High chunk migration | Poor shard key choice | Analyze query patterns and consider resharding with compound shard key |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Global variables
MONGODB_VERSION="8.0"
MONGODB_USER="mongod"
MONGODB_GROUP="mongod"
# Usage function
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --help Show this help message"
echo " --config-only Only install MongoDB without starting services"
echo ""
echo "This script installs MongoDB 8.0 for sharding cluster setup"
exit 1
}
# Error handling and cleanup
cleanup() {
echo -e "${RED}[ERROR]${NC} Installation failed. Cleaning up..."
# Remove potentially incomplete installations
if command -v systemctl &> /dev/null; then
systemctl stop mongod 2>/dev/null || true
systemctl disable mongod 2>/dev/null || true
fi
}
trap cleanup ERR
# Parse arguments
CONFIG_ONLY=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
;;
--config-only)
CONFIG_ONLY=true
shift
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Check prerequisites
echo -e "${YELLOW}[1/8]${NC} Checking prerequisites..."
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
PKG_UPGRADE="apt upgrade -y"
DISTRO_FAMILY="debian"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf check-update || true"
PKG_UPGRADE="dnf upgrade -y"
DISTRO_FAMILY="rhel"
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf check-update || true"
PKG_UPGRADE="dnf upgrade -y"
DISTRO_FAMILY="rhel"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum check-update || true"
PKG_UPGRADE="yum upgrade -y"
DISTRO_FAMILY="rhel"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}/etc/os-release not found. Cannot detect distribution.${NC}"
exit 1
fi
echo -e "${GREEN}Detected distribution: $ID ($DISTRO_FAMILY family)${NC}"
# Update system packages
echo -e "${YELLOW}[2/8]${NC} Updating system packages..."
$PKG_UPDATE
$PKG_UPGRADE
# Install prerequisites
echo -e "${YELLOW}[3/8]${NC} Installing prerequisites..."
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
$PKG_INSTALL wget curl gnupg lsb-release ca-certificates
elif [[ "$DISTRO_FAMILY" == "rhel" ]]; then
$PKG_INSTALL wget curl gnupg2
fi
# Add MongoDB repository
echo -e "${YELLOW}[4/8]${NC} Adding MongoDB repository..."
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
# Import MongoDB GPG key
wget -qO - https://www.mongodb.org/static/pgp/server-${MONGODB_VERSION}.asc | apt-key add -
# Determine codename for repository
if [[ "$ID" == "ubuntu" ]]; then
case "$VERSION_CODENAME" in
focal|jammy|noble)
REPO_CODENAME="jammy"
;;
*)
REPO_CODENAME="jammy"
echo -e "${YELLOW}Warning: Using jammy repository for $VERSION_CODENAME${NC}"
;;
esac
elif [[ "$ID" == "debian" ]]; then
REPO_CODENAME="jammy" # Use Ubuntu jammy for Debian
fi
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${REPO_CODENAME}/mongodb-org/${MONGODB_VERSION} multiverse" | tee /etc/apt/sources.list.d/mongodb-org-${MONGODB_VERSION}.list
$PKG_UPDATE
elif [[ "$DISTRO_FAMILY" == "rhel" ]]; then
# Create MongoDB repository file
tee /etc/yum.repos.d/mongodb-org-${MONGODB_VERSION}.repo << EOF
[mongodb-org-${MONGODB_VERSION}]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/${MONGODB_VERSION}/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-${MONGODB_VERSION}.asc
EOF
fi
# Install MongoDB
echo -e "${YELLOW}[5/8]${NC} Installing MongoDB ${MONGODB_VERSION}..."
$PKG_INSTALL mongodb-org
# Create MongoDB directories with proper permissions
echo -e "${YELLOW}[6/8]${NC} Setting up MongoDB directories and permissions..."
mkdir -p /var/lib/mongo
mkdir -p /var/log/mongodb
mkdir -p /etc/mongod
# Set proper ownership and permissions
chown ${MONGODB_USER}:${MONGODB_GROUP} /var/lib/mongo
chown ${MONGODB_USER}:${MONGODB_GROUP} /var/log/mongodb
chmod 755 /var/lib/mongo
chmod 755 /var/log/mongodb
# Configure MongoDB for sharding
echo -e "${YELLOW}[7/8]${NC} Creating MongoDB configuration for sharding cluster..."
cat > /etc/mongod.conf << 'EOF'
# MongoDB configuration file for sharding cluster
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27017
bindIp: 127.0.0.1
processManagement:
timeZoneInfo: /usr/share/zoneinfo
# Sharding configuration (commented for initial setup)
# Enable these sections based on node role:
#sharding:
# clusterRole: shardsvr # Use 'configsvr' for config servers
#replication:
# replSetName: "shard1" # Change name for different shards/config servers
EOF
# Set proper permissions for config file
chmod 644 /etc/mongod.conf
chown root:root /etc/mongod.conf
# Configure firewall
if [[ "$DISTRO_FAMILY" == "rhel" ]]; then
if systemctl is-active --quiet firewalld; then
echo -e "${YELLOW}Configuring firewalld for MongoDB...${NC}"
firewall-cmd --permanent --add-port=27017/tcp
firewall-cmd --permanent --add-port=27018/tcp # Config server port
firewall-cmd --permanent --add-port=27019/tcp # Mongos port
firewall-cmd --reload
fi
elif [[ "$DISTRO_FAMILY" == "debian" ]]; then
if command -v ufw &> /dev/null && ufw status | grep -q "Status: active"; then
echo -e "${YELLOW}Configuring UFW for MongoDB...${NC}"
ufw allow 27017/tcp
ufw allow 27018/tcp
ufw allow 27019/tcp
fi
fi
# Configure SELinux for RHEL-based systems
if [[ "$DISTRO_FAMILY" == "rhel" ]] && command -v getenforce &> /dev/null && [[ "$(getenforce)" == "Enforcing" ]]; then
echo -e "${YELLOW}Configuring SELinux for MongoDB...${NC}"
setsebool -P mongod_can_network_connect 1 2>/dev/null || true
fi
# Enable and start MongoDB service
if [[ "$CONFIG_ONLY" == "false" ]]; then
echo -e "${YELLOW}[8/8]${NC} Enabling and starting MongoDB service..."
systemctl daemon-reload
systemctl enable mongod
systemctl start mongod
# Wait for MongoDB to start
sleep 5
# Verify installation
echo -e "${YELLOW}Verifying MongoDB installation...${NC}"
if systemctl is-active --quiet mongod; then
echo -e "${GREEN}✓ MongoDB service is running${NC}"
else
echo -e "${RED}✗ MongoDB service failed to start${NC}"
exit 1
fi
if mongosh --eval "db.adminCommand('ismaster')" &>/dev/null; then
echo -e "${GREEN}✓ MongoDB is responding to commands${NC}"
else
echo -e "${RED}✗ MongoDB is not responding${NC}"
exit 1
fi
else
echo -e "${YELLOW}[8/8]${NC} MongoDB installed but not started (--config-only mode)"
fi
echo -e "${GREEN}MongoDB ${MONGODB_VERSION} installation completed successfully!${NC}"
echo -e "${YELLOW}Next steps for sharding cluster setup:${NC}"
echo "1. Edit /etc/mongod.conf to configure sharding role (shardsvr/configsvr)"
echo "2. Configure replica sets for each shard and config servers"
echo "3. Set up mongos routing instances"
echo "4. Initialize sharding and add shards to cluster"
echo ""
echo "Configuration file: /etc/mongod.conf"
echo "Data directory: /var/lib/mongo"
echo "Log file: /var/log/mongodb/mongod.log"
Review the script before running. Execute with: bash install.sh