Skip to content

Instantly share code, notes, and snippets.

@dPacc
Created October 4, 2024 12:13
Show Gist options
  • Save dPacc/257919b4c20604aeb6102a29dfe68655 to your computer and use it in GitHub Desktop.
Save dPacc/257919b4c20604aeb6102a29dfe68655 to your computer and use it in GitHub Desktop.
Self Host MongoDB

Comprehensive Guide to Self-Hosting MongoDB

Table of Contents

  1. Prerequisites
  2. Installing MongoDB
  3. Configuring MongoDB
  4. Securing MongoDB
  5. Starting and Managing MongoDB
  6. Setting Up Users and Authentication
  7. Configuring Firewall
  8. Initializing Replica Set
  9. Restoring Data
  10. Troubleshooting

Prerequisites

  • A Ubuntu server (this guide uses Ubuntu 22.04)
  • Root or sudo access to the server
  • Basic knowledge of terminal commands

Installing MongoDB

  1. Update the package list:

    sudo apt-get update
  2. Install required packages:

    sudo apt-get install -y gnupg
  3. Import the MongoDB public GPG key:

    curl -fsSL https://pgp.mongodb.com/server-7.0.asc | \
    sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg \
    --dearmor
  4. Create a list file for MongoDB:

    echo "deb [ arch=amd64,arm64 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
  5. Update the package list again:

    sudo apt-get update
  6. Install MongoDB:

    sudo apt-get install -y mongodb-org

Configuring MongoDB

  1. Edit the MongoDB configuration file:

    sudo nano /etc/mongod.conf
  2. Here's a detailed mongod.conf file with explanations:

    # mongod.conf
    
    # Where and how to store data.
    storage:
      dbPath: /var/lib/mongodb
      journal:
        enabled: true
    
    # Where to write logging data.
    systemLog:
      destination: file
      logAppend: true
      path: /var/log/mongodb/mongod.log
    
    # Network interfaces
    net:
      port: 27017
      bindIp: 0.0.0.0  # Allow connections from any IP
    
    # How the process runs
    processManagement:
      timeZoneInfo: /usr/share/zoneinfo
    
    # Security
    security:
      authorization: enabled
      keyFile: /etc/mongodb/keyfile  # For replica set authentication
    
    # Replication
    replication:
      replSetName: "myReplicaSet"

    Explanation of key settings:

    • storage.dbPath: Where MongoDB stores its data files
    • systemLog: Logging configuration
    • net.bindIp: 0.0.0.0 allows connections from any IP
    • security.authorization: Enables access control
    • security.keyFile: Used for internal authentication in a replica set
    • replication.replSetName: Name of the replica set
  3. Save and exit the editor (in nano, press Ctrl+X, then Y, then Enter)

Securing MongoDB

  1. Create a keyfile for replica set authentication:
    sudo mkdir -p /etc/mongodb
    sudo openssl rand -base64 756 > /etc/mongodb/keyfile
    sudo chmod 400 /etc/mongodb/keyfile
    sudo chown mongodb:mongodb /etc/mongodb/keyfile

Starting and Managing MongoDB

  1. Start MongoDB:

    sudo systemctl start mongod
  2. Enable MongoDB to start on boot:

    sudo systemctl enable mongod
  3. Check MongoDB status:

    sudo systemctl status mongod

Setting Up Users and Authentication

  1. Connect to MongoDB:

    mongosh
  2. Create an admin user:

    use admin
    db.createUser(
      {
        user: "adminUser",
        pwd: "securePassword",  // Change this!
        roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
      }
    )
  3. Create a user for a specific database:

    use test
    db.createUser(
      {
        user: "dpac",
        pwd: "securePassword",  // Change this!
        roles: [ { role: "readWrite", db: "test" } ]
      }
    )

Configuring Firewall

  1. Allow MongoDB port through UFW:

    sudo ufw allow from YOUR_IP_ADDRESS to any port 27017

    Replace YOUR_IP_ADDRESS with the IP address you want to allow.

  2. Enable UFW if not already enabled:

    sudo ufw enable
  3. Check UFW status:

    sudo ufw status

Initializing Replica Set

  1. Connect to MongoDB:

    mongosh
  2. Initiate the replica set:

    rs.initiate({
      _id: "myReplicaSet",
      members: [
        { _id: 0, host: "YOUR_SERVER_IP:27017" }
      ]
    })

    Replace YOUR_SERVER_IP with your server's actual IP address.

Restoring Data

  1. Restore data from a backup:
    mongorestore --uri "mongodb://dpac:[email protected]:27017/test" --db test /path/to/backup/test/
    Replace securePassword with the actual password for the dpac user.

Troubleshooting

  1. If MongoDB fails to start, check the logs:

    sudo tail -n 100 /var/log/mongodb/mongod.log
  2. If you encounter permission issues:

    sudo chown -R mongodb:mongodb /var/lib/mongodb
    sudo chown -R mongodb:mongodb /var/log/mongodb
  3. If you need to remove and reinstall MongoDB:

    sudo apt-get purge mongodb-org*
    sudo rm -r /var/log/mongodb
    sudo rm -r /var/lib/mongodb

    Then follow the installation steps again.

  4. If you're having connection issues, ensure the bindIp in your mongod.conf is set correctly and that your firewall rules allow the connection.

Remember to replace placeholder passwords with strong, unique passwords in a production environment. Always follow best practices for security when setting up a database server.

This guide should help you set up a self-hosted MongoDB instance. Always refer to the official MongoDB documentation for the most up-to-date and comprehensive information.

@dPacc
Copy link
Author

dPacc commented Oct 10, 2024

MongoDB Replica Set Setup Guide

This guide provides step-by-step instructions for setting up a MongoDB replica set with security measures. The setup includes installing MongoDB, configuring the replica set, setting up authentication, and ensuring proper network security.

Table of Contents

  1. Prerequisites
  2. Installing MongoDB Community Edition
  3. Configuring Security Keyfile
  4. Configuring MongoDB
  5. Initializing the Replica Set
  6. Creating Admin User
  7. Testing Primary and Secondary Nodes
  8. Changing Primary and Secondary Roles
  9. Creating Application Database and Users
  10. Configuring Firewall
  11. Troubleshooting

Prerequisites

  • Ubuntu 22.04 (Jammy) servers
  • Root or sudo access on all servers
  • Stable network connectivity between all servers

Installing MongoDB Community Edition

Perform these steps on all servers in your replica set.

  1. Install required packages:

    sudo apt install software-properties-common gnupg apt-transport-https ca-certificates -y
  2. Import MongoDB GPG key:

    curl -fsSL https://pgp.mongodb.com/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
  3. Add MongoDB repository:

    echo "deb [ arch=amd64,arm64 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
  4. Update package list and install MongoDB:

    sudo apt update
    sudo apt install mongodb-org -y
  5. Verify installation:

    mongod --version
  6. Start and enable MongoDB service:

    sudo systemctl start mongod
    sudo systemctl enable mongod
  7. Check MongoDB status and port:

    sudo systemctl status mongod
    sudo ss -pnltu | grep 27017

Configuring Security Keyfile

Create a security keyfile on all servers:

  1. Generate the keyfile:

    openssl rand -base64 756 > /etc/mongodb-keyfile
  2. Set proper permissions:

    sudo chmod 400 /etc/mongodb-keyfile
    sudo chown mongodb:mongodb /etc/mongodb-keyfile
  3. Verify the keyfile's SHA256 sum on all servers:

    sha256sum /etc/mongodb-keyfile

    If the SHA256 sums are not identical across all servers, copy the keyfile from the primary to secondaries:

    scp [email protected]:/etc/mongodb-keyfile /etc
    sudo chown mongodb:mongodb /etc/mongodb-keyfile
    sudo chmod 400 /etc/mongodb-keyfile
  4. Create necessary directories:

    sudo mkdir -p /var/log/mongodb
    sudo chown -R mongodb:mongodb /var/log/mongodb
    sudo chmod 755 /var/log/mongodb

Configuring MongoDB

  1. Create data directory:

    sudo mkdir -p /data/mongodb
    sudo chown -R mongodb:mongodb /data/mongodb
    sudo chmod -R 700 /data/mongodb
  2. Edit MongoDB configuration file:

    sudo vi /etc/mongod.conf

    Update the following sections:

    storage:
      dbPath: /data/mongodb
    net:
      port: 27017
      bindIp: 0.0.0.0  # Adjust based on your security policies
    security:
      authorization: enabled
      keyFile: /etc/mongodb-keyfile
    replication:
      replSetName: rs0
  3. Restart MongoDB:

    sudo rm /data/mongodb/mongod.lock
    sudo systemctl restart mongod
    sudo systemctl status mongod

Initializing the Replica Set

Perform these steps on the primary server only.

  1. Connect to MongoDB:

    mongosh --port 27017
  2. Initiate the replica set:

    rs.initiate({
      _id: "rs0",
      members: [
        { _id: 0, host: "91.108.110.14:27017" },
        { _id: 1, host: "178.16.138.32:27017" },
        { _id: 2, host: "93.127.167.208:27017" }
      ]
    })

Creating Admin User

On the primary server:

  1. Switch to admin database:

    use admin
  2. Create admin user:

    db.createUser({
      user: "admin",
      pwd: "secureAdminPassword",
      roles: [{ role: "root", db: "admin" }]
    })

Testing Primary and Secondary Nodes

  1. Restart MongoDB on all servers:

    sudo systemctl restart mongod
    sudo systemctl status mongod
  2. Connect to primary:

    mongosh "mongodb://admin:[email protected]:27017/admin?authSource=admin"
  3. Connect to secondaries:

    mongosh "mongodb://admin:[email protected]:27017/admin?authSource=admin&readPreference=secondaryPreferred"
    mongosh "mongodb://admin:[email protected]:27017/admin?authSource=admin&readPreference=secondaryPreferred"
  4. Check replica set status:

    db.isMaster()
    db.hello()
    rs.status()

Changing Primary and Secondary Roles

To change the primary node:

  1. Connect to the current primary:

    var cfg = rs.conf();
  2. Set priorities:

    cfg.members.forEach(function(member) {
      if (member.host === "91.108.110.14:27017") {
        member.priority = 2; // Higher priority to prefer becoming primary
      } else {
        member.priority = 1; // Default priority for other members
      }
    });
  3. Reconfigure the replica set:

    rs.reconfig(cfg)
  4. If necessary, force reconfiguration:

    rs.reconfig(cfg, { force: true })
  5. Optionally, step down the current primary:

    rs.stepDown(60)

Creating Application Database and Users

  1. Create database and user:

    use pepbits
    db.createUser({
      user: "pepadmin",
      pwd: "pepadmin",
      roles: [{ role: "readWrite", db: "pepbits" }]
    })
  2. Test data insertion:

    db.employees.insertOne({
      firstName: "Alice",
      lastName: "Johnson",
      email: "[email protected]",
      age: 29,
      position: "Software Engineer",
      department: "Development",
      startDate: new Date("2022-01-15"),
      skills: ["JavaScript", "Node.js", "MongoDB"],
      address: {
        street: "456 Elm Street",
        city: "Techville",
        state: "CA",
        zip: "90001"
      }
    })
  3. Verify data replication:

    db.employees.find()

Configuring Firewall

Use UFW (Uncomplicated Firewall) to secure your MongoDB servers:

  1. Allow MongoDB port for specific IP:

    sudo ufw allow from YOUR_IP_ADDRESS to any port 27017
  2. Enable UFW:

    sudo ufw enable
  3. Check UFW status:

    sudo ufw status

Troubleshooting

  • If you encounter issues with replica set configuration, ensure all servers have the same keyfile and correct permissions.
  • Check MongoDB logs: sudo tail -f /var/log/mongodb/mongod.log
  • Verify network connectivity between servers.
  • Ensure firewall rules allow communication on port 27017 between replica set members.

Remember to replace placeholder values (like IP addresses and passwords) with your actual configuration details. Always use strong, unique passwords in production environments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment