Back to articles
Technology Insight

Scaling MongoDB Apps Safely: A Complete Guide to Deploying FerretDB on a VPS with a PostgreSQL Backend

May 30, 2026

The Database Dilemma: Developer Agility vs. Data Reliability

In the modern software development landscape, speed and flexibility are paramount. For years, document-oriented databases like MongoDB captured the hearts of developers by offering a schema-less design, intuitive JSON-like queries, and rapid prototyping capabilities. However, changing licensing models and the operational complexities of maintaining separate database ecosystems have forced enterprise architects to reconsider their infrastructure strategies.

Enter FerretDB. FerretDB is an innovative, open-source proxy that translates MongoDB wire protocol queries into SQL, executing them directly against a PostgreSQL backend. This allows development teams to build applications using standard MongoDB drivers and syntax while leveraging the proven reliability, strict ACID compliance, and robust ecosystem of PostgreSQL. In this comprehensive guide, we will explore the architecture of FerretDB and provide a step-by-step blueprint for deploying this powerful combination on a Virtual Private Server (VPS).

Why FerretDB and PostgreSQL? The Strategic Advantages

Choosing FerretDB over a native MongoDB deployment offers several distinct advantages for business infrastructure, resource allocation, and long-term maintainability.

  • Open-Source Sovereignty: Unlike MongoDB, which operates under the Server Side Public License (SSPL), FerretDB is licensed under the Apache 2.0 license, and PostgreSQL uses the PostgreSQL License. This ensures compliance with strict enterprise open-source policies and eliminates vendors lock-in.
  • Unified Database Infrastructure: If your organization already relies on PostgreSQL for relational data, adding FerretDB allows you to support document workloads without provisioning, monitoring, and backing up an entirely separate database engine.
  • Uncompromising Data Integrity: PostgreSQL is renowned for its mature storage engine, transaction management, and robust point-in-time recovery (PITR) capabilities. FerretDB inherits these enterprise-grade features automatically.
"FerretDB brings the best of both worlds: the developer experience of MongoDB paired with the operational peace of mind offered by PostgreSQL."

Architectural Overview: How It Works Under the Hood

Before diving into the deployment process, it is essential to understand the network topology. FerretDB acts as a stateless intermediary layer. When your application sends a query using a standard MongoDB driver, FerretDB intercepts the request, converts the BSON/JSON payload into efficient SQL queries, executes them on PostgreSQL using JSONB data types, and formats the result back into MongoDB-compatible responses.

Because FerretDB is stateless, it can be easily scaled horizontally, restarted, or containerized without risking data loss. The state resides entirely within your secured PostgreSQL instance.

Prerequisites for VPS Deployment

To successfully follow this guide, ensure your Virtual Private Server meets the following minimum requirements:

  • Operating System: Ubuntu 24.04 LTS or Debian 12 (Clean installation recommended).
  • Hardware Specs: Minimum 2 vCPUs, 2GB RAM, and SSD storage (PostgreSQL is I/O intensive).
  • Access: Non-root user with sudo privileges and an SSH key configured.
  • Domain & Firewall: A fully qualified domain name (optional, for SSL) and standard ports open (e.g., 22 for SSH, 27017 for FerretDB, and 5432 if PostgreSQL is exposed remotely).

Step-by-Step Deployment Blueprint

Step 1: System Update and Core Dependencies

First, access your VPS via SSH and ensure all system packages are fully updated. We will use Docker and Docker Compose to streamline the deployment of FerretDB and PostgreSQL, ensuring isolated environments and easy version upgrades.

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git apt-transport-https ca-certificates gnupg

Install Docker Engine and Docker Compose using the official repository script:

curl -fsSL [https://get.docker.com](https://get.docker.com) -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

Log out and log back in to apply the group changes.

Step 2: Configuring the Docker Compose Stack

Create a dedicated directory for your database infrastructure and initialize your configuration files. This setup binds PostgreSQL to a persistent volume to prevent data loss across container restarts.

mkdir ~/ferretdb-stack && cd ~/ferretdb-stack
nano docker-compose.yml

Paste the following production-ready configuration into the file:

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: postgres-backend
    environment:
      POSTGRES_USER: ferret_admin
      POSTGRES_PASSWORD: SecurePassword_ChangeMe_123
      POSTGRES_DB: ferretdb_warehouse
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5432:5432"
    networks:
      - db-network
    restart: always

  ferretdb:
    image: ghcr.io/ferretdb/ferretdb:latest
    container_name: ferretdb-proxy
    environment:
      FERRETDB_POSTGRESQL_URL: "postgres://ferret_admin:SecurePassword_ChangeMe_123@postgres:5432/ferretdb_warehouse"
      FERRETDB_LISTEN_ADDR: "0.0.0.0:27017"
    ports:
      - "27017:27017"
    depends_on:
      - postgres
    networks:
      - db-network
    restart: always

volumes:
  pgdata:

networks:
  db-network:
    driver: bridge

Save and close the file. Security Warning: Replace SecurePassword_ChangeMe_123 with a cryptographically strong passphrase in production setups.

Step 3: Launching the Services

Execute the Docker Compose stack in detached mode to start both engines simultaneously:

docker compose up -d

Verify that both containers are running optimally by inspecting the runtime logs:

docker compose logs -f ferretdb

You should see log lines indicating that FerretDB has successfully established a connection pool with the PostgreSQL backend and is now listening for incoming MongoDB wire protocol connections on port 27017.

Verifying the Connection with MongoDB Syntax

To confirm that the abstraction layer works seamlessly, connect to your server using the official mongosh shell or a database GUI client like MongoDB Compass. If testing locally from the server, run:

docker run --rm -it --network ferretdb-stack_db-network mongo:latest mongosh "mongodb://ferretdb-proxy:27017/test_db"

Once inside the shell, execute standard MongoDB CRUD operations to verify compatibility:

// Insert a document
db.customers.insertOne({ name: "Acme Corp", industry: "SaaS", active: true });

// Query the document
db.customers.find({ industry: "SaaS" });

Behind the scenes, FerretDB converts this into a standard PostgreSQL INSERT INTO ... statement utilizing the highly efficient JSONB type, allowing you to seamlessly read and write without writing a single line of SQL.

Production Hardening and Optimization

While the basic setup gets you up and running, production environments require strict security controls and performance fine-tuning.

1. Implementing UFW Firewall Controls

Never expose your database ports to the open internet without restriction. Limit access to trusted application servers or your specific IP address using the Uncomplicated Firewall (UFW):

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
# Only allow port 27017 from a specific application server IP
sudo ufw allow from 203.0.113.50 to any port 27017
sudo ufw enable

2. Indexing Strategy in FerretDB

When you create an index via the MongoDB driver (e.g., db.collection.createIndex({ field: 1 })), FerretDB translates this into a standard PostgreSQL B-Tree or GIN index over the JSONB properties. Ensure you analyze your access patterns and index heavily queried fields to avoid sequential table scans in the underlying PostgreSQL tables.

3. Automated Backups

Because all data lives in PostgreSQL, you do not need specialty MongoDB backup tools like mongodump. Instead, utilize industry-standard PostgreSQL tools like pg_dump or pg_backups to schedule daily, encrypted backups of the pgdata volume, saving significant time and reducing disaster recovery operational overhead.

Conclusion

Deploying FerretDB on a VPS represents a highly pragmatic architectural choice for modern businesses. It breaks down the artificial silos between relational and non-relational database management systems. By choosing FerretDB, you retain the unparalleled agility of MongoDB's document API while building upon the rock-solid, production-tested foundation of PostgreSQL. This approach optimizes resource consumption, guarantees licensing compliance, and reduces infrastructure complexity—all while ensuring your application remains highly performant and scalable for years to come.

Scaling MongoDB Apps Safely: A Complete Guide to Deploying FerretDB on a VPS with a PostgreSQL Backend | DPTCloud