How to Install and Configure MongoDB on a VPS (Complete Guide)
MongoDB is a document-oriented NoSQL database that stores records as BSON (Binary JSON) documents, enabling schema-free data modeling with horizontal scalability through native sharding. Unlike relational databases, MongoDB requires no predefined table schema, making it the dominant choice for applications with evolving data structures, high write throughput, or hierarchical data relationships.
This guide walks through a production-grade MongoDB deployment on a Linux VPS — covering installation from the official repository, authentication hardening, network access control, TLS configuration, performance tuning, and backup automation. Every step assumes you are operating in a real server environment where security and reliability are non-negotiable.
Prerequisites
Before proceeding, confirm the following:
- A VPS running Ubuntu 20.04 LTS or Ubuntu 22.04 LTS (commands are identical for both)
- Root or
sudo-privileged user access via SSH - A minimum of 2 GB RAM (4 GB recommended for production workloads)
- At least 20 GB of available disk space on a fast storage volume
- UFW or iptables available for firewall management
- Basic familiarity with the Linux command line
> Architecture note: MongoDB's WiredTiger storage engine uses a default internal cache of 50% of (RAM – 1 GB). On a 2 GB VPS, that yields roughly 512 MB of cache. For read-heavy workloads, provision at least 4 GB RAM to avoid constant disk I/O from cache pressure.
MongoDB vs. Other NoSQL Databases: Quick Comparison
| Feature | MongoDB | Redis | Cassandra | CouchDB |
|---|---|---|---|---|
| Data model | Document (BSON) | Key-value | Wide-column | Document (JSON) |
| Query language | MQL (rich queries) | Commands | CQL | Mango / MapReduce |
| Horizontal scaling | Native sharding | Cluster mode | Native | Multi-master |
| ACID transactions | Yes (v4.0+, multi-doc) | Partial (Lua scripts) | Lightweight | Yes |
| Best use case | General-purpose apps, APIs | Caching, sessions | Time-series, IoT | Offline-first sync |
| Disk persistence | Primary store | Optional (RDB/AOF) | Primary store | Primary store |
| Full-text search | Atlas Search / text index | Limited | No | Limited |
Step 1: Update the System
Always begin with a fully patched system. Outdated packages introduce known CVEs that can be exploited before you even install your application stack.
sudo apt update && sudo apt upgrade -yAfter applying kernel or libc updates, reboot to activate the new kernel:
sudo rebootReconnect via SSH after the server comes back online (typically 30–60 seconds).
Step 2: Install MongoDB from the Official Repository
Ubuntu's default apt repositories ship an outdated, community-repackaged version of MongoDB that lacks recent security patches and engine improvements. Always install from MongoDB's official repository.
Add the MongoDB GPG Key and Repository
The apt-key command is deprecated on Ubuntu 22.04. Use the recommended keyring method, which works on both 20.04 and 22.04:
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc |
sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpgAdd the official repository entry:
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ]
https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/7.0 multiverse" |
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list> Version note: Replace 7.0 with your target release (e.g., 6.0) if you require a specific version for application compatibility. MongoDB 7.0 is the current Long-Term Support release as of 2024.
Install MongoDB Packages
sudo apt update
sudo apt install -y mongodb-orgThis installs the following components:
mongod — the primary database daemon
mongos — the sharding router (used in sharded cluster deployments)
mongosh — the modern MongoDB Shell (replaces the legacy mongo binary)
mongodb-database-tools — includes mongodump, mongorestore, mongoexport, and mongoimportPin the Installed Version
Prevent unintended upgrades that could break application compatibility:
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-database hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongosh hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selectionsStep 3: Configure System-Level Prerequisites
MongoDB performs best when certain kernel and filesystem parameters are tuned before the daemon starts.
Set the ulimit for Open Files
MongoDB requires a high file descriptor limit. Create a systemd override:
sudo mkdir -p /etc/systemd/system/mongod.service.d
sudo tee /etc/systemd/system/mongod.service.d/limits.conf > /dev/null <<EOF
[Service]
LimitFNOFILE=64000
LimitNPROC=64000
EOFDisable Transparent Huge Pages (THP)
THP causes significant latency spikes in MongoDB. Disable it persistently:
sudo tee /etc/systemd/system/disable-thp.service > /dev/null <<EOF
[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongod.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null'
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/defrag > /dev/null'
[Install]
WantedBy=basic.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now disable-thpVerify the setting took effect:
cat /sys/kernel/mm/transparent_hugepage/enabledThe output should show [never] as the active value.
Step 4: Start and Enable MongoDB
sudo systemctl daemon-reload
sudo systemctl start mongod
sudo systemctl enable mongodConfirm the daemon is running:
sudo systemctl status mongodLook for Active: active (running) in the output. If the service fails to start, inspect the log immediately:
sudo tail -50 /var/log/mongodb/mongod.logCommon startup failures include:
- Port 27017 already in use — another process is bound to the port; identify it with
sudo ss -tlnp | grep 27017 - Data directory permissions — the
mongoduser must own/var/lib/mongodb; fix withsudo chown -R mongodb:mongodb /var/lib/mongodb - THP still enabled — the WiredTiger engine logs a warning and may degrade performance
Step 5: Secure MongoDB — Authentication and Authorization
This is the most critical section. Unprotected MongoDB instances exposed to the internet have been responsible for thousands of data breaches. The default installation has no authentication, meaning anyone who can reach port 27017 has full read/write access to every database.
Create the Administrative User
Connect to the local MongoDB shell (no authentication required before enabling it):
mongoshInside the shell, switch to the admin database and create a superuser:
use admin
db.createUser({
user: "adminuser",
pwd: passwordPrompt(),
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" }
]
})Using passwordPrompt() instead of a plaintext string prevents the password from appearing in shell history. Type the password when prompted, then exit:
exitEnable Authentication in mongod.conf
Open the MongoDB configuration file:
sudo nano /etc/mongod.confLocate the security section (it will be commented out) and enable authorization:
security:
authorization: enabledSave and exit (Ctrl+X, then Y, then Enter), then restart the daemon:
sudo systemctl restart mongodVerify Authentication Is Enforced
Attempt an unauthenticated connection — it should now fail:
mongosh --eval "db.adminCommand({ listDatabases: 1 })"You should receive an Unauthorized error. Now authenticate properly:
mongosh -u adminuser -p --authenticationDatabase adminCreate Application-Scoped Users
Never use the admin superuser for application connections. Create a least-privilege user for each application database:
use myappdb
db.createUser({
user: "appuser",
pwd: passwordPrompt(),
roles: [
{ role: "readWrite", db: "myappdb" }
]
})Step 6: Configure Network Binding and Firewall Rules
Restrict or Expand bindIp
By default, mongod.conf binds only to 127.0.0.1. This is the correct setting if your application runs on the same VPS. If you need remote access (e.g., from an application server on a separate host), edit /etc/mongod.conf:
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.5Replace 10.0.0.5 with the specific private IP of your application server. Never set bindIp: 0.0.0.0 on a public-facing interface without a firewall rule restricting access to known IPs. Binding to all interfaces with no firewall is the leading cause of MongoDB data exposure incidents.
Restart after changes:
sudo systemctl restart mongodConfigure UFW Firewall Rules
If remote access is required, allow only the specific trusted IP:
sudo ufw allow from 10.0.0.5 to any port 27017 proto tcp
sudo ufw enable
sudo ufw status verboseBlock all other external access to port 27017:
sudo ufw deny 27017UFW processes rules in order — the specific allow from rule above the broad deny rule takes precedence for the trusted IP.
Step 7: Enable TLS/SSL for Encrypted Connections
For any deployment where MongoDB traffic crosses a network — even a private LAN — TLS encryption is mandatory. Without it, credentials and data are transmitted in plaintext.
Generate a self-signed certificate for testing (use a CA-signed certificate in production — consider pairing this with an SSL Certificate for your domain):
sudo mkdir -p /etc/mongodb/ssl
sudo openssl req -newkey rsa:4096 -nodes -keyout /etc/mongodb/ssl/mongodb.key
-x509 -days 365 -out /etc/mongodb/ssl/mongodb.crt
-subj "/CN=your-vps-hostname"
sudo cat /etc/mongodb/ssl/mongodb.crt /etc/mongodb/ssl/mongodb.key |
sudo tee /etc/mongodb/ssl/mongodb.pem > /dev/null
sudo chown -R mongodb:mongodb /etc/mongodb/ssl
sudo chmod 600 /etc/mongodb/ssl/mongodb.pemAdd TLS configuration to /etc/mongod.conf:
net:
port: 27017
bindIp: 127.0.0.1
tls:
mode: requireTLS
certificateKeyFile: /etc/mongodb/ssl/mongodb.pemRestart MongoDB and connect with TLS:
sudo systemctl restart mongod
mongosh --tls --tlsCertificateKeyFile /etc/mongodb/ssl/mongodb.pem
--tlsAllowInvalidCertificates -u adminuser -p --authenticationDatabase adminThe --tlsAllowInvalidCertificates flag is only acceptable for self-signed certificates in development. Remove it when using a CA-signed certificate.
Step 8: Performance Tuning in mongod.conf
For a production deployment on a VPS with dedicated resources, tune the WiredTiger cache and journaling settings. Open /etc/mongod.conf and add or modify the following:
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1.5
operationProfiling:
slowOpThresholdMs: 100
mode: slowOp
replication:
oplogSizeMB: 1024Key tuning parameters explained:
cacheSizeGB— Set this to approximately 50% of available RAM minus 1 GB. On a 4 GB VPS, use1.5. On an 8 GB VPS, use3.5.slowOpThresholdMs— Queries exceeding this threshold (in milliseconds) are logged to the profiler. Lowering this helps identify unindexed queries early.oplogSizeMB— Relevant if you plan to add replica set members later. Pre-sizing the oplog avoids replication lag on high-write workloads.
Apply changes:
sudo systemctl restart mongodStep 9: Backup and Restore with mongodump
Manual Backup
mongodump
--uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"
--out /var/backups/mongodb/$(date +%Y-%m-%d)Manual Restore
mongorestore
--uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"
/var/backups/mongodb/2024-06-15Automate Backups with Cron
Create a dedicated backup script:
sudo tee /usr/local/bin/mongodb-backup.sh > /dev/null <<'EOF'
#!/bin/bash
BACKUP_DIR="/var/backups/mongodb"
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
MONGO_URI="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"
RETENTION_DAYS=7
mkdir -p "${BACKUP_DIR}/${TIMESTAMP}"
mongodump --uri="${MONGO_URI}" --out="${BACKUP_DIR}/${TIMESTAMP}"
find "${BACKUP_DIR}" -maxdepth 1 -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} ;
EOF
sudo chmod +x /usr/local/bin/mongodb-backup.shSchedule it to run daily at 2:00 AM:
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/mongodb-backup.sh >> /var/log/mongodb-backup.log 2>&1") | crontab -> Production consideration: Store backups off-server. Keeping backups on the same VPS as the database provides no protection against disk failure or server compromise. Use rsync, rclone, or an S3-compatible object store to replicate backups to a remote location.
Step 10: Monitor MongoDB Health
Built-in Monitoring Commands
Inside mongosh, run server statistics:
db.serverStatus()
db.stats()
db.currentOp()Use mongostat and mongotop
From the shell, monitor real-time operation counts:
mongostat --uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"Monitor per-collection read/write time:
mongotop --uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"Key Metrics to Watch
| Metric | Warning Threshold | What It Indicates |
|---|---|---|
wiredTiger.cache.bytes currently in cache | > 90% of cacheSizeGB | Cache pressure; increase RAM or reduce dataset |
connections.current | > 80% of connections.available | Connection pool exhaustion; tune app pooling |
opcounters.getmore | Consistently high | Cursor inefficiency; review query patterns |
repl.lag (replica sets) | > 10 seconds | Replication lag; check network and disk I/O |
locks.Global.acquireWaitCount | Any sustained value | Lock contention; review long-running operations |
Choosing the Right Hosting for MongoDB
The performance and reliability of your MongoDB instance are directly tied to the underlying infrastructure. Consider these deployment tiers:
- Development and staging: A standard VPS with 2–4 GB RAM is sufficient for non-production workloads, schema testing, and integration environments.
- Production single-node: A VPS with 4–8 GB RAM, NVMe storage, and a dedicated CPU core handles moderate production traffic for most web applications.
- High-throughput production: A Dedicated Server eliminates the noisy-neighbor effect inherent in virtualized environments. WiredTiger's I/O patterns benefit significantly from bare-metal NVMe arrays.
- ML/analytics workloads: If you are running MongoDB alongside data pipelines, aggregation-heavy analytics, or vector search, GPU Hosting can accelerate downstream processing tasks.
For deployments that require a graphical management interface, VPS with cPanel provides a familiar environment for teams less comfortable with pure CLI administration, though direct mongod.conf editing remains necessary for advanced configuration.
Deployment Decision Matrix
Use this checklist before going live:
- [ ] MongoDB installed from the official repository, version pinned
- [ ]
mongodservice enabled and confirmedactive (running) - [ ] Transparent Huge Pages disabled and verified
- [ ]
ulimitfor file descriptors set to 64000 or higher - [ ] Authentication enabled in
mongod.conf(authorization: enabled) - [ ] Admin user created with
passwordPrompt()— no plaintext passwords in shell history - [ ] Application-specific users created with least-privilege roles
- [ ]
bindIprestricted to localhost or specific trusted IPs only - [ ] UFW rules in place — port 27017 blocked from public internet
- [ ] TLS enabled with a valid certificate
- [ ] WiredTiger cache sized to 50% of (RAM – 1 GB)
- [ ] Slow query profiling enabled (
slowOpThresholdMs: 100) - [ ] Automated daily backups with off-server replication
- [ ] Backup restore tested — a backup you have never restored is not a backup
FAQ
What is the default port MongoDB listens on, and should it be changed?
MongoDB listens on TCP port 27017 by default. Changing it to a non-standard port adds minor obscurity but is not a substitute for authentication and firewall rules. If you change it, update net.port in /etc/mongod.conf and adjust all UFW rules and connection strings accordingly.
Why does MongoDB use so much RAM even with a small dataset?
WiredTiger pre-allocates its internal cache based on the formula max(50% of (RAM - 1 GB), 256 MB). This is intentional — keeping working data in memory eliminates disk reads. If RAM consumption is a concern on a small VPS, explicitly set cacheSizeGB in /etc/mongod.conf to a lower value.
Can I run MongoDB on shared hosting?
No. MongoDB requires a persistent background daemon (mongod), direct filesystem access to its data directory, and the ability to bind to a network port. None of these are available on Shared Web Hosting. A VPS is the minimum viable environment.
What is the difference between mongodump and a filesystem snapshot for backups?
mongodump performs a logical backup — it reads documents through the MongoDB query interface and exports them as BSON files. It is portable and works across versions but is slower and cannot guarantee point-in-time consistency on a live, high-write instance without --oplog. A filesystem snapshot (LVM, ZFS, or cloud block storage snapshot) captures the raw data files at a consistent point in time and is significantly faster for large datasets, but requires the storage engine to be in a consistent state.
How do I check which MongoDB version is installed?
Run the following command from the terminal:
mongod --versionOr from inside mongosh:
db.version()