Introduction
MongoDB is the most widely used NoSQL database, storing data as flexible JSON-like documents instead of the rigid rows and columns of relational databases like MySQL or PostgreSQL. This flexibility makes MongoDB a popular choice for web applications, REST APIs, content management systems, and real-time analytics — anywhere the data schema evolves frequently or documents have varying structures.
Unlike relational databases, MongoDB does not require you to define a table schema before inserting data. You can store documents with different fields in the same collection, add new fields without migrations, and nest complex data structures inside a single document. This makes development faster, especially during prototyping and early product stages where the data model changes frequently.
In this tutorial, you will add the official MongoDB repository to Ubuntu 24.04, install MongoDB Community Edition, enable authentication with an admin user, create an application database and user, perform basic CRUD operations to verify the setup, and configure the firewall. On a Raff VM with NVMe SSD storage, MongoDB's WiredTiger storage engine delivers fast document reads and writes — the combination of low-latency storage and AMD EPYC processors handles demanding query workloads efficiently.
Step 1 — Add the MongoDB Repository
MongoDB is not included in Ubuntu 24.04's default repositories. You need to add the official MongoDB APT repository to get the latest stable release.
Import the MongoDB GPG key:
bashcurl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-8.0.gpg
Add the MongoDB repository for Ubuntu 24.04 (Noble):
bashecho "deb [signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
Update the package index:
bashsudo apt update
You should see the MongoDB repository listed in the output without any errors. If you see a GPG key error, verify the key import command and try again.
Step 2 — Install MongoDB
Install the MongoDB Community Edition meta-package, which includes the server, shell, tools, and mongos router:
bashsudo apt install -y mongodb-org
Start the MongoDB service and enable it to start at boot:
bashsudo systemctl start mongod
sudo systemctl enable mongod
Verify the service is running:
bashsudo systemctl status mongod
You should see active (running) in the output.
Check the installed version:
bashmongod --version
Expected output:
db version v8.0.x
Note
If mongod fails to start, check the log with sudo journalctl -u mongod -e. A common issue on fresh installs is a missing data directory — MongoDB expects /var/lib/mongodb to exist with correct ownership.
Connect to the MongoDB shell to verify it is responding:
bashmongosh
You should see the MongoDB shell prompt:
test>
Type exit to disconnect. At this point, MongoDB is running without authentication — anyone with network access can connect. You will fix this in the next step.
Step 3 — Create the Admin User
Before enabling authentication, create an admin user who can manage databases and other users.
Connect to the MongoDB shell:
bashmongosh
Switch to the admin database:
javascriptuse admin
Create an admin user with the userAdminAnyDatabase and readWriteAnyDatabase roles:
javascriptdb.createUser({
user: "admin",
pwd: "your_strong_admin_password",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
})
Replace your_strong_admin_password with a strong password. You should see { ok: 1 } confirming the user was created.
Exit the shell:
javascriptexit
Tip
Generate a strong password with openssl rand -base64 24. Store it securely — you will need it every time you connect to MongoDB with authentication enabled.
Step 4 — Enable Authentication
By default, MongoDB accepts connections without any credentials. This is a critical security risk on a cloud server. Enable authentication by editing the MongoDB configuration file.
Open the configuration:
bashsudo nano /etc/mongod.conf
Find the #security: section (it is commented out by default) and change it to:
yamlsecurity:
authorization: enabled
Make sure authorization: enabled is indented with two spaces — YAML is whitespace-sensitive.
Also verify the bindIp setting in the net: section:
yamlnet:
port: 27017
bindIp: 127.0.0.1
This ensures MongoDB only accepts connections from localhost. You will modify this later if you need remote access.
Save the file and restart MongoDB:
bashsudo systemctl restart mongod
Verify it restarted successfully:
bashsudo systemctl status mongod
Now test that authentication is enforced. Connect without credentials:
bashmongosh
Try to list databases:
javascriptshow dbs
You should see an authorization error. This confirms authentication is working. Exit and reconnect with your admin credentials:
bashmongosh -u admin -p --authenticationDatabase admin
Enter your password when prompted. Now show dbs should display the admin, config, and local databases.
Step 5 — Create an Application Database and User
Running your application as the admin user is a security risk. Create a dedicated database and user for each application.
While connected as admin, switch to a new database (MongoDB creates it automatically when you first write data):
javascriptuse appdb
Create a user with read-write access to this database only:
javascriptdb.createUser({
user: "appuser",
pwd: "your_app_password",
roles: [
{ role: "readWrite", db: "appdb" }
]
})
Exit and reconnect as the application user to verify:
bashmongosh -u appuser -p --authenticationDatabase appdb
Switch to the application database:
javascriptuse appdb
You should be able to read and write in appdb but not access other databases.
Step 6 — Test with Basic CRUD Operations
Verify the database works by performing basic Create, Read, Update, and Delete operations.
Insert documents into a collection (MongoDB creates the collection automatically):
javascriptdb.products.insertMany([
{ name: "Cloud VM Small", price: 3.99, cpu: 1, ram: 1 },
{ name: "Cloud VM Medium", price: 19.99, cpu: 2, ram: 4 },
{ name: "Cloud VM Large", price: 64.00, cpu: 8, ram: 16 }
])
Read all documents:
javascriptdb.products.find()
Find a specific document:
javascriptdb.products.findOne({ name: "Cloud VM Medium" })
Update a document:
javascriptdb.products.updateOne(
{ name: "Cloud VM Small" },
{ $set: { price: 4.99 } }
)
Delete a document:
javascriptdb.products.deleteOne({ name: "Cloud VM Large" })
Count documents in the collection:
javascriptdb.products.countDocuments()
Notice that you did not define a schema or create a table before inserting data. This is the fundamental difference between MongoDB and relational databases — the schema is implicit in the documents themselves.
Clean up the test data:
javascriptdb.products.drop()
exit
Step 7 — Configure the Firewall
By default, MongoDB listens on port 27017 and accepts connections only from localhost. If your application runs on the same server, no firewall changes are needed.
If you need to allow MongoDB connections from another Raff VM on the same private network:
First, update the bind address in /etc/mongod.conf:
yamlnet:
port: 27017
bindIp: 127.0.0.1,10.0.0.5
Replace 10.0.0.5 with your server's private IP. Restart MongoDB:
bashsudo systemctl restart mongod
Then allow access from the application server's IP:
bashsudo ufw allow from 10.0.0.0/24 to any port 27017
Warning
Never bind MongoDB to 0.0.0.0 or open port 27017 to the internet without authentication. Unsecured MongoDB instances are actively scanned by automated bots and can be compromised within hours of exposure.
Useful MongoDB Commands
Here are the commands you will use most often in the mongosh shell:
javascriptshow dbs // List all databases
use dbname // Switch to a database
show collections // List collections in current database
db.collection.find() // List all documents
db.collection.find().pretty() // Formatted output
db.collection.countDocuments() // Count documents
db.collection.createIndex({ field: 1 }) // Create an index
db.stats() // Database statistics
db.collection.stats() // Collection statistics
Administration commands:
javascriptdb.getUsers() // List users in current database
db.createUser({...}) // Create a user
db.dropUser("username") // Delete a user
db.shutdownServer() // Graceful shutdown (from admin db)
Configuration files and paths:
/etc/mongod.conf— Main configuration file/var/lib/mongodb/— Data directory/var/log/mongodb/mongod.log— Log file
Service management:
bashsudo systemctl start mongod # Start MongoDB
sudo systemctl stop mongod # Stop MongoDB
sudo systemctl restart mongod # Restart MongoDB
sudo systemctl status mongod # Check status
Conclusion
You have installed MongoDB Community Edition on your Raff Ubuntu 24.04 VM, created an admin user, enabled authentication, set up an application database with a dedicated user, and verified the setup with CRUD operations. Your server is ready to host MongoDB-powered applications.
From here, you can:
- Connect your Node.js application using the official MongoDB Node.js driver or Mongoose ODM
- Connect your Python application using PyMongo
- Set up automated backups using
mongodumpcombined with Raff VM snapshots - Create indexes on frequently queried fields to improve read performance
- Monitor MongoDB performance with Prometheus and Grafana using the MongoDB exporter
- Manage your database alongside other services using Portainer
MongoDB's WiredTiger storage engine benefits directly from NVMe SSD storage on Raff VMs — document reads and index lookups complete in microseconds rather than milliseconds. For write-heavy workloads, the 4 vCPU / 8 GB RAM tier ($36.00/month) provides a larger WiredTiger cache, which keeps more frequently accessed documents in memory.
This tutorial was tested by our systems engineering team on a Raff CPU-Optimized Tier 3 VM with MongoDB 8.0.

