How to Use FerretDB: The Beginner's Guide (First Docker Run, First mongosh, First Collection, and the Postgres Rule)
CodexFuse Team · 2026-10-31T06:43:15.381Z · 11 min read
Learn how to use FerretDB: run the eval Docker image, connect with mongosh, create your first collection, and understand the Postgres DocumentDB rule — the MongoDB-compatible, Apache 2.0 way.
If you want to learn how to use FerretDB, the good news is that you already know half of it: every command, driver, and graphical tool you know from MongoDB works against it. FerretDB is a free, Apache 2.0-licensed proxy that speaks the MongoDB wire protocol and stores your documents in PostgreSQL — which means MongoDB-shaped data without the SSPL license terms that pushed so many teams away. This beginner's guide walks you from a one-line Docker demo to your first mongosh session, your first collection, and the one Postgres rule that trips up every beginner.
All you need to follow along is Docker on your machine — if you have never touched it, start with our Docker beginner guide first, then come back. No MongoDB server, no Postgres install, and no account are required — this FerretDB tutorial assumes nothing beyond basic comfort with a terminal.
How Do You Use FerretDB for the First Time?
You use FerretDB for the first time by starting it in one Docker command, connecting with mongosh using an ordinary MongoDB connection string, and creating databases and collections exactly as you would in MongoDB — because FerretDB translates the wire protocol, not the query language. Here is the complete first-use arc in six steps:
- Start the eval image. Run the one-line demo container that bundles FerretDB with a throwaway Postgres. This is for learning only — never for real data.
- Connect with mongosh. Point the MongoDB shell at
mongodb://ferret:[email protected]:27017/and you land in a working database. - Create your first collection. Pick a database with
use workshopand rundb.createCollection('books'). - Insert and read a document. Use
insertOneandfind— the exact commands MongoDB users already know. - Create a real user. Run
db.createUserso you are not relying on the demo credentials. - Learn the Postgres rule. When the demo ends, swap the eval image for the production image plus a real Postgres carrying the DocumentDB extension — the rest of this guide shows you how.
What Is FerretDB, Really?
FerretDB is a stateless Go proxy that accepts the MongoDB wire protocol (5.0 and newer) on port 27017 and translates every BSON command into SQL against PostgreSQL — so your application keeps its mongodb:// connection string while the data physically lives in Postgres tables. Microsoft's open-sourced DocumentDB extension gives PostgreSQL a native BSON type, which is what makes the translation faithful instead of a JSON-in-a-text-column hack. Grasping the FerretDB PostgreSQL pairing — proxy up front, Postgres at the back — is the single mental model that makes everything else in this guide click.
The project relicensed to Apache 2.0 with the 2.0 GA release in March 2025, which is the whole reason it exists in its current form: teams that could not accept the SSPL terms on MongoDB's own server software get a genuinely open-source, MongoDB-compatible database. According to the maintainers, roughly 80 percent of real-world workloads already run on FerretDB unmodified.
FerretDB vs MongoDB: What Changes and What Stays the Same?
Your drivers, queries, and tooling stay exactly the same; what changes is the storage engine underneath and the license above it. This comparison is an original synthesis of the official FerretDB documentation and the FerretDB 2.0 technical explainer, both checked for this guide:
| Aspect | MongoDB (self-hosted server) | FerretDB 2.x |
|---|---|---|
| Connection string | mongodb://… | Identical mongodb://… |
| Query language | MQL, aggregation pipelines | Same MQL, majority of pipeline stages |
| Drivers and shells | Official drivers, mongosh, Compass | Same — wire-protocol compatible |
| Storage engine | WiredTiger | PostgreSQL + DocumentDB extension |
| Server license | SSPL | Apache 2.0 |
| Sharding | Supported | Not supported |
| Multi-document transactions | Supported (ACID) | Not supported |
| Authentication | MongoDB users (SCRAM) | PostgreSQL users; client mechanism SCRAM-SHA-256 |
| Authorization / roles | Full RBAC | Not yet supported (roles must be empty) |
The practical takeaway: if your workload fits in a single replica set and never needed sharding or multi-document transactions, FerretDB is a drop-in replacement. If it did need those, FerretDB is not your database — pick accordingly before you migrate a byte.
How Do You Install FerretDB with Docker?
For a first look, run the eval image in a single command; for anything real, run the production image next to a Postgres container that carries the DocumentDB extension, using Docker Compose. The two paths exist for different jobs, and mixing them up is the most common beginner mistake:
| Eval image | Production image | |
|---|---|---|
| Image | ghcr.io/ferretdb/ferretdb-eval:2 | ghcr.io/ferretdb/ferretdb:2.7.0 |
| Postgres | Bundled, throwaway | Separate container with the DocumentDB extension |
| Data survival | Gone when the container stops (--rm) | Persisted in a volume |
| Use for | Demos, tutorials, experiments | Everything else |
The FerretDB Docker lineup actually ships three images: the eval image for demos, the production image for real deployments, and a development image with extra debugging features that the docs warn is significantly slower and not for production use — you will only ever need the first two. The eval one-liner, from the official quick-start flow:
docker run -d --rm --name ferretdb -p 27017:27017 \
-e POSTGRES_USER=ferret \
-e POSTGRES_PASSWORD=<choose-a-password> \
ghcr.io/ferretdb/ferretdb-eval:2
For the production path, the official Docker guide (checked today) recommends pinning the full image tag — currently 2.7.0, the latest release — and pairing it with the matching pre-packaged Postgres image:
services:
postgres:
image: ghcr.io/ferretdb/postgres-documentdb:17-0.107.0-ferretdb-2.7.0
restart: on-failure
environment:
- POSTGRES_USER=username
- POSTGRES_PASSWORD=<choose-a-password>
- POSTGRES_DB=postgres
volumes:
- ./data:/var/lib/postgresql/data
ferretdb:
image: ghcr.io/ferretdb/ferretdb:2.7.0
restart: on-failure
ports:
- 27017:27017
environment:
- FERRETDB_POSTGRESQL_URL=postgres://username:password@postgres:5432/postgres
networks:
default:
name: ferretdb
Start it with docker compose up -d. This production FerretDB setup stores data in ./data on the host, so your documents survive container restarts. Three details from the official docs are worth memorizing: FerretDB requires a postgres database to be initialized for the connection; always pin the full tag (like 2.7.0, not :2) so redeploys do not surprise you; and when updating, upgrade the DocumentDB image first — the FerretDB release notes name the matching DocumentDB version for each release.
How Do You Connect to FerretDB with mongosh?
You connect exactly as you would to MongoDB: hand mongosh a mongodb:// URI, because FerretDB listens on the standard MongoDB port 27017 and negotiates the same wire protocol. Against the eval container above:
mongosh mongodb://ferret:<your-password>@127.0.0.1:27017/
Against the Compose stack, the official guide's example URI is simply mongodb://username:[email protected]/. Once connected, your FerretDB mongosh session behaves exactly like a MongoDB shell — the prompt, the helpers, and the error messages are all MongoDB-shaped. If you do not have mongosh installed locally, the docs give a neat fallback — run the shell inside a throwaway MongoDB container attached to the same Docker network:
docker run --rm -it --network=ferretdb --entrypoint=mongosh \
mongo mongodb://username:password@ferretdb/
One authentication fact to file away, verified in the official authentication docs today: FerretDB stores no credentials itself and relies entirely on PostgreSQL's authentication. Auth is on by default, and at the moment only the SCRAM-SHA-256 mechanism is supported on the client side.
How Do You Create Your First Collection and Insert Documents?
Use a database with use, create a collection with db.createCollection, and insert with insertOne — every document lands as BSON inside PostgreSQL, but you never touch SQL yourself. Here is a complete worked example you can paste into mongosh right now:
use workshop
db.createCollection('books')
db.books.insertOne({
title: 'The Hobbit',
author: 'J.R.R. Tolkien',
year: 1937,
genres: ['fantasy', 'adventure']
})
db.books.insertOne({
title: 'Dune',
author: 'Frank Herbert',
year: 1965,
genres: ['science fiction', 'adventure']
})
db.books.find({ genres: 'adventure' }, { title: 1, year: 1, _id: 0 })
// Aggregation works too — count books per genre:
db.books.aggregate([
{ $unwind: '$genres' },
{ $group: { _id: '$genres', count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
Notice that nothing about this session betrayed the Postgres underneath: the shell, the commands, and the results are indistinguishable from MongoDB. That invisibility is the entire product.
How Does Authentication Work in FerretDB?
FerretDB does not store users itself — every credential is a PostgreSQL user, and authentication is enabled by default, so a client without valid credentials can connect but cannot do anything. You can create users two ways: directly in Postgres with CREATE USER, or from inside FerretDB with the familiar MongoDB command:
db.createUser({
user: 'appuser',
pwd: '<strong-password>',
roles: []
})
The empty roles array is not a placeholder you forgot to fill in — authorization is not yet supported in FerretDB 2.x, and the docs explicitly say to pass an empty array for now. Two more auth facts from the official docs: you can disable authentication with the FERRETDB_AUTH=false environment variable or the --no-auth flag, which the docs mark as not recommended for production; and for local Docker Compose setups, Postgres may use trust authentication, meaning anyone who can reach the Postgres container can connect without a password even if you set one — read up on securing it before the database holds anything real.
How Do You Explore FerretDB Data in MongoDB Compass?
The FerretDB Compass connection takes one paste: drop the same mongodb:// connection string into MongoDB Compass and browse your Postgres-backed collections visually — Compass cannot tell it is talking to FerretDB. The vendor's own walkthrough shows connecting Compass to a FerretDB instance, then using the visual query builder, schema analyzer, and aggregation pipeline builder against collections that physically live in PostgreSQL.
This is the moment the value proposition clicks for most beginners: the graphical tooling, the drivers, and the shell you already know keep working, while the operational story — backups, replication, monitoring — becomes the Postgres operational story your team already understands.
What Are the Limits of FerretDB 2.x Beginners Hit?
FerretDB does not do sharding or multi-document transactions, authorization is not yet supported, and the eval image is not a production database — know these before you fall in love with the demo. The honest list, from the 2.0 technical explainer and the official docs:
- No sharding. Horizontal scaling across shards is not supported; scale vertically or shard at the application layer.
- No multi-document transactions. Single-document atomicity holds, but ACID transactions across documents do not — even though Postgres itself supports them.
- No authorization roles yet. Authentication gates access, but fine-grained role-based access control is still on the roadmap.
- Some enterprise-only MongoDB features are absent, such as the encrypted storage engine.
- The eval image is for demos only. Production needs the full image plus a real Postgres with the DocumentDB extension — that is the Postgres rule from the first section.
None of these disqualify FerretDB for the majority of apps — the maintainers report about 80 percent of real-world workloads run unmodified — but check the feature list against your workload's must-haves before migrating.
Where Should Your FerretDB Live: Laptop, VPS, or Managed Cloud?
Keep the eval image on your laptop for learning, run the production Compose stack on a VPS you control, and pick a managed FerretDB host only when you would rather someone else run Postgres. If you need a refresher on the server side of that decision, read what is VPS hosting first — the Compose stack above is exactly the kind of workload a small VPS eats for breakfast.
Looking for a MongoDB alternative, self-hosted on infrastructure you control? FerretDB sits in the document-database lane of the self-hosted world. If your data is relational instead, the edge-relational lane belongs to Turso — see our Turso beginner guide. If you want a whole backend-as-a-service rather than a database you operate, that is the BaaS lane — see our Supabase beginner guide (and yes, people do run FerretDB against a Supabase Postgres to get MongoDB compatibility on top of it). On the managed side, the 2.0 explainer lists FerretDB Cloud, Civo, Tembo, Elestio, and Cozystack; on Kubernetes, the official Helm chart works with operators like StackGres, Crunchy, and CloudNativePG. Enable telemetry when you deploy — the docs recommend it so you get notified about new releases.
Sources
- FerretDB official docs — Docker installation (production image
ghcr.io/ferretdb/ferretdb:2.7.0, matching DocumentDB Postgres image, full-tag pinning, update order), crawled 2026-10-31 - FerretDB official docs — Authentication (PostgreSQL-backed auth, client mechanism SCRAM-SHA-256 only,
FERRETDB_AUTH/--no-auth, empty roles array), crawled 2026-10-31 - GitHub FerretDB/FerretDB releases API — latest stable v2.7.0, released November 2025, checked 2026-10-31
- Bright Coding Blog — "FerretDB: The Open-Source MongoDB Alternative Built on PostgreSQL" (eval one-liner, DocumentDB extension background, 2.0 GA March 2025, ~80% workload compatibility, sharding/transaction limits), October 2026
- Supabase on dev.to — "NoSQL Postgres: Add MongoDB compatibility to your Supabase projects with FerretDB" (Docker run with
FERRETDB_POSTGRESQL_URL, mongosh via container, Fly.io deploy notes) - FerretDB Blog — "Visually Explore Your FerretDB Data in MongoDB Compass" and "20 must-try MongoDB operations and queries on FerretDB" (Compass connection, supported operations breadth)
Frequently Asked Questions
Is FerretDB really free for commercial use?
Yes. The FerretDB license is Apache 2.0: since the 2.0 GA release in March 2025, FerretDB is licensed under Apache 2.0 — you can run it commercially, modify it, and embed it without the SSPL terms that apply to MongoDB's own server software. "MongoDB" itself remains MongoDB Inc.'s trademark, which is why FerretDB is described as MongoDB-compatible rather than as MongoDB.
Can I run FerretDB in production?
Yes, with the production image — not the eval image. Production means ghcr.io/ferretdb/ferretdb (pin the full tag, currently 2.7.0) pointed at a real PostgreSQL carrying the DocumentDB extension, with data on a persisted volume and authentication enabled. When updating, upgrade the DocumentDB image first, then the FerretDB tag, per the release notes.
Does FerretDB support sharding or multi-document transactions?
No. FerretDB 2.x does not support sharding or multi-document ACID transactions, and authorization roles are not yet implemented either. If your workload needs any of those, FerretDB is the wrong database — the maintainers position it for the roughly 80 percent of workloads that run unmodified without them.
Which tools and drivers work with FerretDB?
Anything that speaks the MongoDB wire protocol 5.0 or newer: all official MongoDB drivers, mongosh, MongoDB Compass, mongoimport, and BI connectors. Your existing connection strings and queries work unchanged, which is why migration is usually a connection-string swap rather than a rewrite.
How is FerretDB different from just storing JSON in PostgreSQL?
Storing JSON in Postgres means rewriting your queries and tooling for SQL/JSON operators. FerretDB keeps the entire MongoDB surface — drivers, shell, Compass, aggregation pipelines — while Postgres with the DocumentDB extension provides a native BSON type underneath. You get document-database ergonomics with Postgres operations: backups, replication, and monitoring you already know.