Creating a MongoDB Cluster on Pilvio
In this tutorial, we will create a MongoDB replica set cluster on three Pilvio VMs, using a private network for communication between nodes.
What we will build
- 3-node MongoDB 7 replica set
- Pilvio private network for secure communication between nodes
- Keyfile authentication between cluster nodes
- Backups to StorageVault (S3)
Prerequisites
- Pilvio account and API token (see overview)
- Basic knowledge of MongoDB
- Ability to create at least 3 VMs (billing account)
Step 1: Creating a private network
All MongoDB nodes must be in the same private network:
# Create a private network (or use the default network)
curl "https://api.pilvio.com/v1/network/network?name=mongodb-cluster" \
-H "apikey: SINU_PILVIO_TOKEN" \
-X POST
Note the uuid from the response -- you will need it when creating VMs.
Step 2: Creating VMs
Create 3 VMs in the same private network:
# Node 1 (primary)
curl "https://api.pilvio.com/v1/user-resource/vm" \
-H "apikey: SINU_PILVIO_TOKEN" \
-X POST \
-d "name=mongo-node-1" \
-d "os_name=ubuntu" \
-d "os_version=24.04" \
-d "vcpu=2" -d "ram=4096" -d "disks=50" \
-d "username=deploy" \
-d "password=TurvalineParool123!" \
-d "network_uuid=SINU_NETWORK_UUID" \
-d "reserve_public_ip=False"
# Node 2 (secondary)
curl "https://api.pilvio.com/v1/user-resource/vm" \
-H "apikey: SINU_PILVIO_TOKEN" \
-X POST \
-d "name=mongo-node-2" \
-d "os_name=ubuntu" \
-d "os_version=24.04" \
-d "vcpu=2" -d "ram=4096" -d "disks=50" \
-d "username=deploy" \
-d "password=TurvalineParool123!" \
-d "network_uuid=SINU_NETWORK_UUID" \
-d "reserve_public_ip=False"
# Node 3 (secondary/arbiter)
curl "https://api.pilvio.com/v1/user-resource/vm" \
-H "apikey: SINU_PILVIO_TOKEN" \
-X POST \
-d "name=mongo-node-3" \
-d "os_name=ubuntu" \
-d "os_version=24.04" \
-d "vcpu=2" -d "ram=4096" -d "disks=50" \
-d "username=deploy" \
-d "password=TurvalineParool123!" \
-d "network_uuid=SINU_NETWORK_UUID" \
-d "reserve_public_ip=False"
Note:
reserve_public_ip=False-- database nodes do not need a public IP. Manage them through a jump host or connect from a VM that has a Floating IP.
Note each VM's private_ipv4:
mongo-node-1: 10.x.x.1
mongo-node-2: 10.x.x.2
mongo-node-3: 10.x.x.3
Step 3: Firewall
curl "https://api.pilvio.com/v1/network/firewall" \
-H "apikey: SINU_PILVIO_TOKEN" \
-H "Content-Type: application/json" \
-X POST \
--data '{
"name": "mongodb-cluster-fw",
"rules": [
{
"protocol": "tcp",
"direction": "inbound",
"port_start": 22,
"port_end": 22,
"endpoint_spec_type": "ip_prefixes",
"endpoint_spec": ["10.0.0.0/8"]
},
{
"protocol": "tcp",
"direction": "inbound",
"port_start": 27017,
"port_end": 27017,
"endpoint_spec_type": "ip_prefixes",
"endpoint_spec": ["10.0.0.0/8"]
}
]
}'
Attach the firewall to all three VMs.
Step 4: Installing MongoDB (on all nodes)
Connect to each node (through a jump host) and run:
# MongoDB 7 GPG võti ja repo
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/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-org
Step 5: Keyfile authentication
Create a keyfile on one node and copy it to the others:
# On Node 1:
openssl rand -base64 756 > /tmp/mongodb-keyfile
chmod 400 /tmp/mongodb-keyfile
sudo cp /tmp/mongodb-keyfile /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile
# Copy to other nodes
scp /tmp/mongodb-keyfile deploy@10.x.x.2:/tmp/
scp /tmp/mongodb-keyfile deploy@10.x.x.3:/tmp/
# On each node:
sudo cp /tmp/mongodb-keyfile /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile
Step 6: Configuring MongoDB (on all nodes)
Edit /etc/mongod.conf on each node:
storage:
dbPath: /var/lib/mongodb
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27017
bindIp: 0.0.0.0 # Tulemüür piirab ligipääsu
security:
keyFile: /etc/mongodb-keyfile
authorization: enabled
replication:
replSetName: "pilvio-rs"
Start MongoDB on all nodes:
sudo systemctl enable --now mongod
Step 7: Initializing the replica set
Connect to Node 1 and initialize the cluster:
mongosh --host 10.x.x.1
# Initsialiseerimne
rs.initiate({
_id: "pilvio-rs",
members: [
{ _id: 0, host: "10.x.x.1:27017", priority: 2 },
{ _id: 1, host: "10.x.x.2:27017", priority: 1 },
{ _id: 2, host: "10.x.x.3:27017", priority: 1 }
]
})
# Check status
rs.status()
Creating an admin user
// Kasuta admin andmebaasi
use admin
db.createUser({
user: "admin",
pwd: "tugev-admin-parool",
roles: [{ role: "root", db: "admin" }]
})
// Rakenduse kasutaja
use myapp
db.createUser({
user: "app_user",
pwd: "tugev-app-parool",
roles: [{ role: "readWrite", db: "myapp" }]
})
Step 8: Backups to StorageVault
Create the file /home/deploy/backup-mongo.sh (on the primary node):
#!/bin/bash
set -euo pipefail
BUCKET="minu-mongo-backups"
S3_ENDPOINT="https://s3.pilvio.com:8080"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="/tmp/mongo-backups/${DATE}"
# Dump
mongodump \
--uri="mongodb://admin:tugev-admin-parool@10.x.x.1:27017/myapp?authSource=admin&replicaSet=pilvio-rs" \
--out="$BACKUP_DIR" \
--gzip
# Pakendi ja lae üles
tar -cf - -C "$BACKUP_DIR" . | \
aws s3 cp - "s3://${BUCKET}/mongodb/${DATE}.tar" \
--endpoint-url "$S3_ENDPOINT"
# Puhasta
rm -rf "$BACKUP_DIR"
echo "[$(date)] MongoDB varundamine lõpetatud"
chmod +x /home/deploy/backup-mongo.sh
(crontab -l 2>/dev/null; echo "0 3 * * * /home/deploy/backup-mongo.sh >> /var/log/mongo-backup.log 2>&1") | crontab -
Step 9: Restoring
# Download
aws s3 cp s3://minu-mongo-backups/mongodb/20250211-030000.tar /tmp/ \
--endpoint-url https://s3.pilvio.com:8080
mkdir -p /tmp/mongo-restore
tar -xf /tmp/20250211-030000.tar -C /tmp/mongo-restore
# Restore
mongorestore \
--uri="mongodb://admin:tugev-admin-parool@10.x.x.1:27017/?authSource=admin&replicaSet=pilvio-rs" \
--gzip \
/tmp/mongo-restore
Connecting to the application
# MongoDB connection string (replica set)
mongodb://app_user:tugev-app-parool@10.x.x.1:27017,10.x.x.2:27017,10.x.x.3:27017/myapp?authSource=myapp&replicaSet=pilvio-rs
// Node.js näide
const { MongoClient } = require('mongodb');
const uri = 'mongodb://app_user:tugev-app-parool@10.x.x.1:27017,10.x.x.2:27017,10.x.x.3:27017/myapp?authSource=myapp&replicaSet=pilvio-rs';
const client = new MongoClient(uri);
# Python näide
from pymongo import MongoClient
client = MongoClient(
'mongodb://app_user:tugev-app-parool@10.x.x.1:27017,10.x.x.2:27017,10.x.x.3:27017/myapp',
authSource='myapp',
replicaSet='pilvio-rs'
)
Next steps: Connect your MongoDB cluster to your Node.js or Go backend.