Databases Azure

FerretDB on Ubuntu 24.04 on Azure User Guide

| Product: FerretDB on Ubuntu 24.04 LTS on Azure

Overview

FerretDB is the open-source MongoDB alternative. It speaks the MongoDB wire protocol, so any MongoDB driver or mongosh connects to it unchanged, but it stores your data in PostgreSQL via the DocumentDB extension. You get MongoDB-compatible document operations on a fully open-source, Apache-2.0 stack with PostgreSQL's durability and tooling underneath. The cloudimg image installs FerretDB 2.7.0 on top of PostgreSQL 17 with the official DocumentDB extension, runs each as a dedicated system user, stores the PostgreSQL data directory on a dedicated Azure data disk, and rotates a unique MongoDB password into the image on first boot. Backed by 24/7 cloudimg support.

What is included:

  • FerretDB 2.7.0 (ferretdb) - the MongoDB-compatible database, Apache-2.0 licensed
  • PostgreSQL 17 with the official DocumentDB extension 0.107.0 as the storage backend
  • A unique per-VM MongoDB password generated on first boot (no shared default credential)
  • The PostgreSQL data directory on a dedicated 30 GiB Azure data disk at /var/lib/ferretdb
  • Loopback-only MongoDB wire-protocol listener on 27017 with SCRAM-SHA-256 authentication
  • A debug/health HTTP listener on 127.0.0.1:8088 (/debug/livez, /debug/readyz)
  • 24/7 cloudimg support

This is a database product: FerretDB listens on 127.0.0.1:27017 only by default. The MongoDB wire-protocol port is not opened to the internet until you open it in your NSG - connect locally on the VM, over an SSH tunnel, or open 27017 deliberately (see Step 8).

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point. NSG inbound: allow 22/tcp from your management network. Open 27017/tcp only when you intend to reach FerretDB remotely (Step 8).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for FerretDB by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) only. Then Review + create -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name ferretdb \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm FerretDB is installed and running

FerretDB runs alongside its PostgreSQL backend. Confirm the version and that both services are active, then check the listeners:

ferretdb --version
systemctl is-active postgresql.service ferretdb.service
sudo ss -tln | grep -E ':27017|:8088|:5432'

You should see FerretDB v2.7.0, both services active, and the loopback-only listeners:

version: v2.7.0
active
active
LISTEN 0  4096  127.0.0.1:5432   0.0.0.0:*
LISTEN 0  4096  127.0.0.1:8088   0.0.0.0:*
LISTEN 0  4096  127.0.0.1:27017  0.0.0.0:*

FerretDB version, services active and loopback listeners

Step 5 - Retrieve your per-VM MongoDB password

Each VM generates its own unique MongoDB password on first boot and writes it to a root-only credentials file. The MongoDB username is admin:

sudo cat /root/ferretdb-credentials.txt

The file contains FERRETDB_USERNAME, FERRETDB_PASSWORD, the connection string and the access instructions. Store the password in your secrets manager. In the commands below, <FERRETDB_PASSWORD> stands for the value of FERRETDB_PASSWORD.

Step 6 - Connect and authenticate with mongosh

FerretDB requires authentication (SCRAM-SHA-256, delegated to PostgreSQL). Connect with mongosh using the per-VM admin credentials and run a ping:

mongosh "mongodb://admin:<FERRETDB_PASSWORD>@127.0.0.1:27017/?authMechanism=SCRAM-SHA-256" \
  --quiet --eval 'db.runCommand({ping:1})'
connected to FerretDB v2.7.0
{ ok: 1 }

A wrong password is rejected with an authentication error, so the database is never open without the credential. Any MongoDB driver (Node, Python pymongo, Go, Java, etc.) connects with the same mongodb://admin:<password>@host:27017/ URI.

mongosh connecting, authenticating and running ping

Step 7 - Store and query documents

FerretDB speaks the MongoDB wire protocol, so MongoDB CRUD works unchanged. Insert documents, read one back, and run a query:

mongosh "mongodb://admin:<FERRETDB_PASSWORD>@127.0.0.1:27017/catalog?authMechanism=SCRAM-SHA-256" --quiet --eval '
  db.products.deleteMany({});
  db.products.insertMany([
    {_id:1, name:"widget", price:9.99, tags:["a","b"]},
    {_id:2, name:"gadget", price:19.5, tags:["c"]}
  ]);
  print("inserted: " + db.products.countDocuments({}));
  printjson(db.products.findOne({_id:1}));
  db.products.find({price:{$gt:10}}).forEach(d => print(d.name + " = " + d.price));
'
inserted: 2
{ _id: 1, name: 'widget', price: 9.99, tags: [ 'a', 'b' ] }
gadget = 19.5

mongosh insertMany and find document round-trip

Step 8 - Open the MongoDB wire-protocol port for remote access

By default FerretDB binds to 127.0.0.1:27017 only and the port is not exposed - this is the secure default. To reach it from your workstation or application you have two options.

Option A - SSH tunnel (no NSG change, good for admin access):

# On your workstation:
ssh -L 27017:127.0.0.1:27017 azureuser@<vm-public-ip>

# In another terminal, with a local mongosh:
mongosh "mongodb://admin:<FERRETDB_PASSWORD>@127.0.0.1:27017/?authMechanism=SCRAM-SHA-256"

Option B - bind publicly and open the NSG port (for applications):

# 1. On the VM, set the listen address to all interfaces and restart:
sudo sed -i 's|^FERRETDB_LISTEN_ADDR=.*|FERRETDB_LISTEN_ADDR=0.0.0.0:27017|' /etc/ferretdb/ferretdb.env
sudo systemctl restart ferretdb
# 2. Open 27017/tcp in your Azure NSG (restrict the source to your app subnet):
az network nsg rule create --resource-group <your-rg> --nsg-name <your-nsg> \
  --name allow-mongodb --priority 1010 --access Allow --protocol Tcp \
  --destination-port-ranges 27017 --source-address-prefixes <your-app-cidr>

Then connect from your application with the public connection string:

mongodb://admin:<FERRETDB_PASSWORD>@<vm-public-ip>:27017/

Authentication is always enforced. Never expose 27017 to the internet without restricting the NSG source and using TLS termination in front of FerretDB.

Step 9 - Confirm health and the document store

FerretDB exposes a debug/health listener on 127.0.0.1:8088. /debug/livez is a liveness probe and /debug/readyz is a readiness probe that confirms the PostgreSQL + DocumentDB backend is serving. Check both, then list databases and collections:

curl -fsS -o /dev/null -w 'livez: HTTP %{http_code}\n' http://127.0.0.1:8088/debug/livez
curl -fsS -o /dev/null -w 'readyz: HTTP %{http_code}\n' http://127.0.0.1:8088/debug/readyz
mongosh "mongodb://admin:<FERRETDB_PASSWORD>@127.0.0.1:27017/catalog?authMechanism=SCRAM-SHA-256" \
  --quiet --eval 'db.adminCommand({listDatabases:1}).databases.forEach(d => print(d.name)); print("---"); db.getCollectionNames().forEach(c => print(c))'
livez: HTTP 200
readyz: HTTP 200
catalog
postgres
---
products

FerretDB health endpoints and database listing

Maintenance

  • Persistence: the PostgreSQL data directory (the document store) lives on the dedicated data disk at /var/lib/ferretdb, so your data survives reboots and the volume is independently resizable.
  • Password: the MongoDB user admin is a PostgreSQL role; rotate its password with sudo -u postgres psql -c "ALTER ROLE admin WITH PASSWORD '<new>';" then update FERRETDB_POSTGRESQL_URL in /etc/ferretdb/ferretdb.env and sudo systemctl restart ferretdb.
  • Adding users: create more MongoDB users as PostgreSQL roles - sudo -u postgres psql -c "CREATE ROLE app WITH LOGIN PASSWORD '...';" - or with db.createUser({user:'app', pwd:'...', roles:[]}) in mongosh.
  • Tuning: edit /var/lib/ferretdb/pg17/postgresql.conf (for example shared_buffers, work_mem) and sudo systemctl restart postgresql.
  • Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.
  • Compatibility: FerretDB targets the MongoDB wire protocol - existing MongoDB drivers, libraries and tooling work against 27017.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.

FerretDB is a trademark of FerretDB Inc. MongoDB is a trademark of MongoDB, Inc. PostgreSQL is a trademark of the PostgreSQL Community Association. This image is provided by cloudimg and is not affiliated with or endorsed by FerretDB Inc., MongoDB, Inc. or the PostgreSQL Community Association.