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.