In this tutorial, you’ll install MongoDB 8.0 Community Edition on Ubuntu 24.04 from MongoDB’s official APT repository, create an administrator and application user, enable access control, keep the database local to the VM, and verify the installation with authenticated CRUD operations.
MongoDB is a document database that stores records as BSON documents rather than relational rows. It is commonly used for APIs, content-heavy applications, event data, catalogs, and workloads that benefit from flexible document structures.
Raff supports 3,000+ customers and 15,000+ VMs in its us-east region. Raff Linux VMs provide KVM virtualization, full root access, NVMe storage, and 3 Gbps unmetered bandwidth for self-hosted database workloads.
Prerequisites:
- A Raff Linux VM running Ubuntu 24.04
- SSH access with a user that has sudo privileges
- At least 2 GB RAM for development or light workloads; 4 GB or more is a better production starting point
- A 64-bit x86_64 or supported ARM64 system
- A backup plan before modifying an existing MongoDB installation
📌 Local-only design: This tutorial keeps MongoDB bound to
127.0.0.1. Applications running on the same VM can connect locally, while port27017remains unavailable from the public internet.
The original workflow was tested on a Raff VM with 2 vCPU and 4 GB RAM. The installation and connection steps were reviewed against MongoDB 8.0 documentation in July 2026.
Step 1 — Update Ubuntu and check for conflicting packages
Update the package index and install current system updates:
sudo apt update sudo apt upgrade -y
Install the packages required for MongoDB’s official repository and firewall checks:
sudo apt install -y gnupg curl ca-certificates ufw
Verify the Ubuntu release and CPU architecture:
. /etc/os-release printf '%s | codename=%s | arch=%s\n' \ "$PRETTY_NAME" "$VERSION_CODENAME" "$(dpkg --print-architecture)"
Expected output includes:
Ubuntu 24.04 codename=noble arch=amd64
MongoDB’s official package is named mongodb-org. The unrelated mongodb package from Ubuntu conflicts with it. Check whether that package is installed:
dpkg -l | awk '$1 == "ii" && $2 == "mongodb" { print $2, $3 }'
A fresh VM should return no output. If mongodb is listed, identify and back up any existing data before removing the conflicting package.
Step 2 — Add the MongoDB 8.0 APT repository
Import MongoDB’s official 8.0 signing key:
curl -fsSL https://pgp.mongodb.com/server-8.0.asc | \ sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \ --dearmor
Create the Ubuntu 24.04 Noble repository file:
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.0 multiverse" | \ sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list > /dev/null
Refresh the package index:
sudo apt update
Verify package availability and repository origin:
apt-cache policy mongodb-org | sed -n '1,16p'
Expected output includes:
mongodb-org: Candidate: https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0
The exact package revision changes as MongoDB publishes maintenance and security releases.
MongoDB documents the same repository method in its Ubuntu installation guide.
Step 3 — Install MongoDB Community Edition
Install the official MongoDB Community Edition metapackage:
sudo apt install -y mongodb-org
The metapackage installs the MongoDB server, mongosh, database tools, and supporting components.
Verify the installed versions:
mongod --version | sed -n '1,5p' mongosh --version
Expected output includes:
db version v8.0
The complete version number may be newer than the example.
Verify the package source:
apt-cache policy mongodb-org-server mongodb-mongosh | \ grep -E 'Installed:|repo.mongodb.org' | head -n 10
Step 4 — Start and verify MongoDB
Start MongoDB and enable it at boot:
sudo systemctl enable --now mongod
Verify the service state:
systemctl is-active mongod systemctl is-enabled mongod
Expected output:
active enabled
Confirm that MongoDB accepts local connections:
mongosh --quiet --eval 'db.runCommand({ ping: 1 })'
Expected output:
{ ok: 1 }
Check the listening socket:
sudo ss -lntp | grep ':27017'
Expected output includes:
127.0.0.1:27017
If the service does not start, inspect the status and log:
sudo systemctl status mongod --no-pager sudo tail -n 80 /var/log/mongodb/mongod.log
Step 5 — Create the MongoDB administrator
Create the first administrator before enabling access control. Read the password silently and expose it only to the temporary mongosh process:
read -rsp "MongoDB admin password: " MONGO_ADMIN_PASSWORD echo export MONGO_ADMIN_PASSWORD mongosh --quiet --eval ' const adminDb = db.getSiblingDB("admin"); adminDb.createUser({ user: "admin", pwd: process.env.MONGO_ADMIN_PASSWORD, roles: [ { role: "userAdminAnyDatabase", db: "admin" }, { role: "dbAdminAnyDatabase", db: "admin" } ] }); printjson(adminDb.getUser("admin")); ' unset MONGO_ADMIN_PASSWORD
Expected output includes:
user: 'admin' db: 'admin'
MongoDB Shell supports reading environment variables through process.env, keeping the password out of the command text and shell history.
⚠️ Credential rule: Use a unique password and store it in a secrets manager or protected deployment environment. Do not place production database passwords in application source code or screenshots.
Step 6 — Enable MongoDB access control
Back up the MongoDB configuration file:
sudo cp /etc/mongod.conf /etc/mongod.conf.before-auth
Open the configuration file:
sudo nano /etc/mongod.conf
Find the commented security section or add the following top-level block:
security: authorization: enabled
YAML indentation matters. authorization must be indented with two spaces under security.
Test that the file contains only one active security block:
sudo grep -nE '^security:|^[[:space:]]+authorization:' /etc/mongod.conf
Expected output includes:
security: authorization: enabled
Restart MongoDB:
sudo systemctl restart mongod
Verify that the service is active:
systemctl is-active mongod
Expected output:
active
Verify that an unauthenticated command is rejected:
mongosh --quiet --eval 'db.getSiblingDB("admin").getUsers()'
Expected output includes an authorization error.
Connect as the administrator. --password without a value prompts securely and hides the input:
mongosh --quiet \ --username admin \ --authenticationDatabase admin \ --eval 'db.runCommand({ connectionStatus: 1 }).authInfo.authenticatedUsers' \ --password
Expected output includes:
user: 'admin' db: 'admin'
Step 7 — Create an application database user
Create a database-specific user with readWrite access only to raffapp.
Read the new application password silently:
read -rsp "MongoDB application password: " MONGO_APP_PASSWORD echo export MONGO_APP_PASSWORD
Run the user-creation command as the authenticated administrator:
mongosh --quiet \ --username admin \ --authenticationDatabase admin \ --eval ' const appDb = db.getSiblingDB("raffapp"); appDb.createUser({ user: "raffappuser", pwd: process.env.MONGO_APP_PASSWORD, roles: [ { role: "readWrite", db: "raffapp" } ] }); printjson(appDb.getUser("raffappuser")); ' \ --password
Enter the administrator password when prompted. Then remove the application password from the environment:
unset MONGO_APP_PASSWORD
Expected output includes:
user: 'raffappuser' db: 'raffapp' role: 'readWrite'
The application should use raffappuser, not the administrator account.
Step 8 — Verify authenticated CRUD operations
Connect as the application user and run a complete create, read, update, and delete test:
mongosh "mongodb://127.0.0.1:27017/raffapp" \ --quiet \ --username raffappuser \ --authenticationDatabase raffapp \ --eval ' const collection = db.getSiblingDB("raffapp").tutorial_check; collection.deleteMany({ name: "raff-mongodb-test" }); const inserted = collection.insertOne({ name: "raff-mongodb-test", status: "created", createdAt: new Date() }); const created = collection.findOne({ name: "raff-mongodb-test" }); const updated = collection.updateOne( { name: "raff-mongodb-test" }, { $set: { status: "verified" } } ); const verified = collection.findOne({ name: "raff-mongodb-test" }); const deleted = collection.deleteOne({ name: "raff-mongodb-test" }); printjson({ insertedId: inserted.insertedId, createdStatus: created.status, modifiedCount: updated.modifiedCount, verifiedStatus: verified.status, deletedCount: deleted.deletedCount }); ' \ --password
Enter the application password when prompted.
Expected output includes:
createdStatus: 'created' modifiedCount: 1 verifiedStatus: 'verified' deletedCount: 1
This confirms that the application user can authenticate and modify data only in its assigned database.
Step 9 — Verify local binding and firewall protection
Confirm MongoDB’s configured bind address:
sudo grep -nE '^[[:space:]]*bindIp:' /etc/mongod.conf
Expected output:
bindIp: 127.0.0.1
Confirm the active socket again:
sudo ss -lntp | grep ':27017'
Expected output includes only the loopback address:
127.0.0.1:27017
Allow your SSH access path before enabling UFW:
sudo ufw allow OpenSSH
If the OpenSSH profile is unavailable, allow the SSH port directly:
sudo ufw allow 22/tcp
Add a deny rule for MongoDB as defense in depth and enable UFW:
sudo ufw deny 27017/tcp sudo ufw --force enable
Verify the firewall rules:
sudo ufw status numbered
Expected output includes:
OpenSSH ALLOW IN 27017/tcp DENY IN
📌 Important: The firewall rule is not a replacement for
bindIp: 127.0.0.1. The bind address prevents MongoDB from listening on public interfaces; UFW provides a second control.
For an application and database running on separate VMs, use a private network and restrict access to the application server’s private address. Never expose MongoDB directly to the public internet. Compare managed and self-hosted databases before choosing the operational model.
Step 10 — Run the final verification
Run the final service and network checks:
echo "MongoDB service:" systemctl is-active mongod echo "Boot status:" systemctl is-enabled mongod echo "Listening socket:" sudo ss -lntp | grep ':27017' echo "Firewall:" sudo ufw status numbered echo "Recent service log:" sudo tail -n 10 /var/log/mongodb/mongod.log
Verify the authenticated application connection one final time:
mongosh "mongodb://127.0.0.1:27017/raffapp" \ --quiet \ --username raffappuser \ --authenticationDatabase raffapp \ --eval 'printjson({ user: db.runCommand({ connectionStatus: 1 }).authInfo.authenticatedUsers, ping: db.runCommand({ ping: 1 }) })' \ --password
The installation is complete when:
- MongoDB 8.0 is installed from the official
mongodb-orgrepository - The
mongodservice is active and enabled - Access control rejects unauthenticated database administration
- The administrator and application user can authenticate
- The application user completes authenticated CRUD operations
- MongoDB listens only on
127.0.0.1:27017 - UFW blocks inbound public access to port
27017