Software & Configuration

MongoDB

Install and configure MongoDB on Linux, manage databases and users, replica sets, and basic performance tuning.

MongoDB is a document-oriented NoSQL database that stores data in flexible JSON-like documents (BSON). Ideal for applications with dynamic schemas, high write throughput, or hierarchical data.

Install MongoDB 7.x on Ubuntu/Debian

# Import GPG key
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
  gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg

# Add repository (Ubuntu 22.04)
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" \
  | tee /etc/apt/sources.list.d/mongodb-org-7.0.list

apt-get update
apt-get install -y mongodb-org

systemctl enable --now mongod
systemctl status mongod

Basic Configuration

Main config file: /etc/mongod.conf

# /etc/mongod.conf
storage:
  dbPath: /var/lib/mongodb

systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true

net:
  port: 27017
  bindIp: 127.0.0.1   # change to 0.0.0.0 to allow remote connections

security:
  authorization: enabled   # enable after creating admin user

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

After editing:

systemctl restart mongod

Connect with mongosh

# Local connection
mongosh

# With auth
mongosh -u admin -p --authenticationDatabase admin

# Remote
mongosh "mongodb://user:password@host:27017/dbname"

Create Admin User

Create the admin user before enabling authorization: enabled in mongod.conf, otherwise you'll be locked out.

use admin
db.createUser({
  user: "admin",
  pwd: passwordPrompt(),
  roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
})

Then enable auth in /etc/mongod.conf and restart.

Create a Database and User

use myapp

db.createUser({
  user: "myapp_user",
  pwd: "strongpassword",
  roles: [ { role: "readWrite", db: "myapp" } ]
})

MongoDB creates the database automatically on first write.

Basic Operations

// Insert
db.users.insertOne({ name: "Mario", email: "mario@example.com", age: 30 })
db.users.insertMany([{ name: "Luigi" }, { name: "Peach" }])

// Find
db.users.find()
db.users.find({ age: { $gt: 25 } })
db.users.findOne({ email: "mario@example.com" })

// Update
db.users.updateOne({ name: "Mario" }, { $set: { age: 31 } })
db.users.updateMany({ age: { $lt: 18 } }, { $set: { minor: true } })

// Delete
db.users.deleteOne({ name: "Luigi" })
db.users.deleteMany({ minor: true })

// Count
db.users.countDocuments({ age: { $gt: 25 } })

Indexes

// Create index
db.users.createIndex({ email: 1 }, { unique: true })
db.users.createIndex({ name: 1, age: -1 })   // compound

// Text search index
db.articles.createIndex({ content: "text" })
db.articles.find({ $text: { $search: "mongodb tutorial" } })

// List indexes
db.users.getIndexes()

// Drop index
db.users.dropIndex("email_1")

// Explain query plan (check if index is used)
db.users.find({ email: "mario@example.com" }).explain("executionStats")

Backup and Restore

# Dump all databases
mongodump --out /backup/mongo-$(date +%F)

# Dump specific database
mongodump --db myapp --out /backup/mongo-$(date +%F)

# With auth
mongodump -u admin -p password --authenticationDatabase admin \
  --db myapp --out /backup/

# Restore
mongorestore /backup/mongo-2024-01-01/

# Restore specific database
mongorestore --db myapp /backup/mongo-2024-01-01/myapp/

Replica Set (High Availability)

A replica set requires at least 3 nodes (1 primary + 2 secondaries).

On all 3 nodes, edit /etc/mongod.conf:

replication:
  replSetName: "rs0"

net:
  bindIp: 0.0.0.0

On the primary node, initiate the replica set:

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1:27017" },
    { _id: 1, host: "mongo2:27017" },
    { _id: 2, host: "mongo3:27017" }
  ]
})

// Check status
rs.status()

Connection string for replica set:

mongodb://user:pass@mongo1:27017,mongo2:27017,mongo3:27017/myapp?replicaSet=rs0

Allow Remote Connections

# /etc/mongod.conf
net:
  bindIp: 0.0.0.0
# Open firewall (allow only your app server, not the world)
ufw allow from 10.0.0.5 to any port 27017
systemctl restart mongod

Never expose MongoDB port 27017 directly to the internet. Always use firewall rules or a VPN/SSH tunnel for remote access.

Performance Tuning

// Check slow queries (operations > 100ms)
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)

// Current operations
db.currentOp({ active: true, secs_running: { $gt: 5 } })

// Kill a long-running operation
db.killOp(opId)

// Database stats
db.stats()
db.collection.stats()

mongod.conf tuning for production:

storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2   # default: 50% of RAM minus 1GB

Useful mongosh Commands

// List databases
show dbs

// List collections
show collections

// Switch database
use myapp

// Drop database (careful!)
db.dropDatabase()

// Server status
db.serverStatus()

// Current connections
db.serverStatus().connections

MongoDB Compass

MongoDB Compass is the official GUI. Connect with:

mongodb://admin:password@localhost:27017/?authSource=admin

For remote access via SSH tunnel:

ssh -L 27017:localhost:27017 user@your-server
# Then connect Compass to localhost:27017

On this page