
- MongoDB
- Ubuntu
- Database
- Security
- Next.js
MongoDB Community Setup Guide
A comprehensive guide to installing, configuring, and securing MongoDB Community Edition on Ubuntu 24.04, including authentication, network binding, TLS/SSL, automated backups, and Next.js integration.
This guide walks through installing MongoDB Community Edition on Ubuntu 24.04 (Noble Numbat), securing it with authentication and TLS/SSL, setting up automated backups, and connecting it to a Next.js application. Commands reflect the current stable release — check the official MongoDB docs if a newer version is available.
Installation
1. Import the MongoDB GPG key
Import the signing key to verify package integrity:
sudo apt-get install gnupg curl
curl -fsSL https://pgp.mongodb.com/server-8.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \
--dearmor
2. Add the MongoDB repository
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.3 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-8.3.list
3. Install MongoDB
Update the package database and install:
sudo apt-get update
sudo apt-get install -y mongodb-org
This installs the MongoDB server, mongosh, and the standard tools.
4. Start and enable the service
sudo systemctl start mongod
sudo systemctl enable mongod
Verify the service is running:
sudo systemctl status mongod
You should see output showing the service is active (running).
5. Review the default configuration
MongoDB’s configuration lives at /etc/mongod.conf:
sudo nano /etc/mongod.conf
Key defaults to note:
# Network settings
net:
port: 27017 # Default port
bindIp: 127.0.0.1 # Only allows local connections by default
# Storage
storage:
dbPath: /var/lib/mongodb
# Process management
processManagement:
timeZoneInfo: /usr/share/zoneinfo
After any configuration change, restart MongoDB:
sudo systemctl restart mongod
Security
1. Create an admin user
Connect to the MongoDB shell:
mongosh
Create a root admin user:
use admin
db.createUser(
{
user: "adminUser",
pwd: "secure_password_here",
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
}
)
exit
2. Enable authentication
Edit /etc/mongod.conf and add the security section:
security:
authorization: enabled
Restart MongoDB:
sudo systemctl restart mongod
3. Configure network binding
By default, MongoDB only listens on localhost. If your application is on the same server, leave this as-is. To allow connections from specific remote hosts:
net:
port: 27017
bindIp: 127.0.0.1 # Localhost only (default)
# bindIp: 127.0.0.1,192.168.1.100 # Allow a specific IP
# bindIp: 0.0.0.0 # Allow all IPs (not recommended)
Security warning: Remote connections must always be combined with firewall rules, TLS/SSL, and strong authentication.
4. Set up TLS/SSL
Generate a self-signed certificate (for testing; use a CA-signed cert in production):
# Create directory for certificates
sudo mkdir -p /etc/ssl/mongodb
cd /etc/ssl/mongodb
# Generate self-signed certificate
sudo openssl req -newkey rsa:4096 -x509 -sha256 -days 365 -nodes \
-out mongodb-cert.pem \
-keyout mongodb-key.pem
# Set appropriate permissions
sudo chmod 600 mongodb-key.pem mongodb-cert.pem
sudo chown mongodb:mongodb mongodb-key.pem mongodb-cert.pem
Update /etc/mongod.conf to require SSL:
net:
port: 27017
bindIp: 127.0.0.1
ssl:
mode: requireSSL
PEMKeyFile: /etc/ssl/mongodb/mongodb-cert.pem
PEMKeyPassword: "your_password_if_any"
5. Set up automated backups
Create the backup directory and script:
sudo mkdir -p /var/backups/mongodb
sudo nano /usr/local/bin/mongodb-backup.sh
Backup script content:
#!/bin/bash
BACKUP_DIR="/var/backups/mongodb/$(date +%Y-%m-%d_%H-%M-%S)"
LOG_FILE="/var/log/mongodb/backup_$(date +%Y-%m-%d).log"
mkdir -p $BACKUP_DIR
echo "Backup started at $(date)" >> $LOG_FILE
mongodump --port 27017 \
--authenticationDatabase "admin" \
--username "adminUser" \
--password "secure_password_here" \
--out $BACKUP_DIR \
--gzip
echo "Backup completed at $(date)" >> $LOG_FILE
# Remove backups older than 14 days
find /var/backups/mongodb -type d -mtime +14 -exec rm -rf {} \; 2>/dev/null || true
Make the script executable and schedule it via cron:
sudo chmod +x /usr/local/bin/mongodb-backup.sh
# Edit crontab — add a daily run at 2 AM
sudo crontab -e
# Add: 0 2 * * * /usr/local/bin/mongodb-backup.sh
To restore from a backup:
# List available backups
ls -la /var/backups/mongodb/
# Restore from a specific backup
mongorestore --port 27017 \
--authenticationDatabase "admin" \
--username "adminUser" \
--password "secure_password_here" \
--gzip \
/var/backups/mongodb/2025-03-25_02-00-00/
Security Best Practices
- Use strong, unique passwords for all MongoDB users.
- Follow the principle of least privilege — only grant users the permissions they actually need.
- Keep MongoDB updated to ensure security patches are applied.
- Implement IP whitelisting to restrict access to trusted sources.
- Use TLS/SSL for all connections in production environments.
- Regularly test your backup restoration process, not just the backup creation.
- Monitor logs for suspicious activity and set up automated alerts.
Integrating MongoDB with Next.js
If you haven’t deployed your Next.js application yet, see Deploying Next.js with Nginx or Deploying Next.js with Apache2 for server setup.
Connection utility
Create a connection singleton in lib/mongodb.ts to avoid opening a new connection on every request:
// lib/mongodb.ts
import { MongoClient } from 'mongodb'
if (!process.env.MONGODB_URI) {
throw new Error('Please add your MongoDB URI to .env.local')
}
const uri = process.env.MONGODB_URI
const options = {}
let client: MongoClient
let clientPromise: Promise<MongoClient>
if (process.env.NODE_ENV === 'development') {
// In development, preserve the connection across HMR reloads
const globalWithMongo = global as typeof globalThis & {
_mongoClientPromise?: Promise<MongoClient>
}
if (!globalWithMongo._mongoClientPromise) {
client = new MongoClient(uri, options)
globalWithMongo._mongoClientPromise = client.connect()
}
clientPromise = globalWithMongo._mongoClientPromise
} else {
client = new MongoClient(uri, options)
clientPromise = client.connect()
}
export default clientPromise
Environment variables
Add the connection string to .env.local:
MONGODB_URI=mongodb://adminUser:secure_password@127.0.0.1:27017/mydb?authSource=admin
Using the connection in API routes
// app/api/users/route.ts
import { NextResponse } from 'next/server'
import clientPromise from '@/lib/mongodb'
export async function GET() {
try {
const client = await clientPromise
const db = client.db("mydb")
const users = await db.collection("users").find({}).limit(10).toArray()
return NextResponse.json({ users })
} catch (e) {
console.error(e)
return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 })
}
}
Frequently Asked Questions
Can MongoDB and Next.js run on the same server?
Yes, for small to medium applications this is fine. For larger workloads consider separating them — dedicated database servers give you better scalability, independent resource tuning, and cleaner security boundaries.
How do I monitor MongoDB performance?
Use the built-in tools (db.stats(), db.serverStatus()), or third-party solutions like Prometheus with the MongoDB exporter, MongoDB Atlas monitoring, or commercial tools like Datadog.
Should I use MongoDB Atlas instead of self-hosting?
Atlas offers automatic backups, scaling, and managed security updates at the cost of less control and ongoing subscription fees. Self-hosting gives you full control but requires more operational work. For most production apps, Atlas is the pragmatic choice unless cost or data residency requirements push you toward self-hosting.
How do I backup and restore my database?
Use mongodump to create backups and mongorestore to restore them, as shown in the backup section above. Always verify that your restore process works before you actually need it.