PostgreSQL Mongo 模式
使用 DocumentDB 与 FerretDB Docker APP,让 PostgreSQL 提供 MongoDB 协议兼容能力。
mongo 配置模板是一个 PostgreSQL 部署模式,而不是独立的 Pigsty 模块。它由以下组件组成:
- 由标准
PGSQL模块管理的 PostgreSQL 18 documentdb扩展及其预加载库- 通过 Pigsty Docker APP 工作流部署的无状态 FerretDB 代理
所有数据、高可用、备份、监控与生命周期管理仍由 PostgreSQL 负责;FerretDB 只提供 MongoDB 线协议兼容端点。
快速开始
模板默认部署在单节点 10.10.10.10 上,FerretDB 默认只监听本机回环地址。
如果尚未安装 mongosh,请单独安装,或使用其他兼容 MongoDB 协议的客户端。
./configure -c mongo
./deploy.yml
./docker.yml -l pg-meta
./app.yml -l pg-meta
mongosh 'mongodb://mongod:DBUser.Mongo@127.0.0.1:27017/'
模板声明了专用的 PostgreSQL 用户 mongod。FerretDB 默认启用认证,但尚未实现 MongoDB 授权角色;真正的安全边界仍然是 PostgreSQL。
架构
| 层次 | 实现 | 职责 |
|---|---|---|
| 数据层 | PostgreSQL + DocumentDB | 持久化、事务、高可用、PITR、ACL 与监控 |
| 协议层 | FerretDB Docker APP | 无状态的 MongoDB 线协议兼容 |
| 访问层 | 默认 127.0.0.1:27017 | 本机 MongoDB 客户端入口 |
容器通过 host.docker.internal 连接 Pigsty 本机的 5436 主库服务。默认 Mongo 端点不会暴露到网络;只有确实需要远程访问时才应修改 FERRETDB_BIND_ADDR。
配置
---
#==============================================================#
# File : mongo.yml
# Desc : PostgreSQL Mongo Mode (DocumentDB + FerretDB)
# Ctime : 2025-02-23
# Mtime : 2026-08-05
# Docs : https://pigsty.io/docs/conf/mongo
# License : Apache-2.0 @ https://pigsty.io/docs/about/license/
# Copyright : 2018-2026 Ruohang Feng / Vonng (rh@vonng.com)
#==============================================================#
# This is the PostgreSQL Mongo mode template, powered by DocumentDB + FerretDB
# It provides a MongoDB wire-compatible endpoint backed by PostgreSQL
# This config template works with PostgreSQL 16, 17, 18
# tutorial: https://pigsty.io/docs/conf/mongo
#
# Usage:
# curl https://repo.pigsty.io/get | bash
# ./configure -c mongo
# ./deploy.yml
# ./docker.yml -l pg-meta
# ./app.yml -l pg-meta
# # install mongosh separately if it is not already available
# mongosh 'mongodb://mongod:DBUser.Mongo@127.0.0.1:27017/'
all:
children:
infra: { hosts: { 10.10.10.10: { infra_seq: 1 }} ,vars: { repo_enabled: false }}
etcd:
hosts:
10.10.10.10: { etcd_seq: 1 }
#10.10.10.11: { etcd_seq: 2 }
#10.10.10.12: { etcd_seq: 3 }
vars: { etcd_cluster: etcd }
#minio: { hosts: { 10.10.10.10: { minio_seq: 1 }} ,vars: { minio_cluster: minio }}
#----------------------------------#
# PGSQL Database Cluster
#----------------------------------#
pg-meta:
hosts:
10.10.10.10: { pg_seq: 1, pg_role: primary }
vars:
pg_cluster: pg-meta
pg_users:
- { name: mongod ,password: DBUser.Mongo ,superuser: true ,comment: FerretDB backend user }
- { name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [dbrole_admin ] ,comment: pigsty admin user }
- { name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer }
pg_databases:
- { name: postgres, extensions: [ documentdb, postgis, vector, pg_cron, rum ]} # run on the postgres database
pg_hba_rules:
- { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
# WARNING: demo/dev only. Avoid world access for dbsu in production.
- { user: postgres , db: all ,addr: world ,auth: pwd ,title: 'dbsu password access everywhere' }
- { user: all ,db: all ,addr: localhost ,order: 1 ,auth: trust ,title: 'documentdb localhost trust access' }
- { user: all ,db: all ,addr: local ,order: 1 ,auth: trust ,title: 'documentdb local trust access' }
- { user: all ,db: all ,addr: intra ,auth: pwd ,title: 'everyone intranet access with password' ,order: 800 }
pg_parameters: { cron.database_name: postgres }
pg_extensions: [ documentdb, postgis, pgvector, pg_cron, rum ]
pg_libs: 'pg_documentdb, pg_documentdb_core, pg_documentdb_extended_rum, pg_cron, pg_stat_statements, auto_explain'
pg_crontab: # https://pigsty.io/docs/pgsql/admin/crontab
- '00 01 * * * /pg/bin/pg-backup full'
# FerretDB Docker APP on the same node, exposed at 127.0.0.1:27017
docker_enabled: true
app: ferretdb
apps:
ferretdb:
conf:
FERRETDB_IMAGE: ghcr.io/ferretdb/ferretdb:2.7.0
FERRETDB_POSTGRESQL_URL: 'postgres://mongod:DBUser.Mongo@host.docker.internal:5436/postgres?pool_min_conns=1&pool_max_conns=20'
FERRETDB_BIND_ADDR: 127.0.0.1
FERRETDB_PORT: 27017
FERRETDB_LISTEN_ADDR: ':27017'
FERRETDB_AUTH: true
FERRETDB_TELEMETRY: disabled
#--------------------------------------------------------------------------#
# OPTIONAL: Three-node PostgreSQL + DocumentDB + FerretDB HA cluster
# Uncomment this entire block and the two additional etcd members above.
# Then run: ./docker.yml -l pg-mongo && ./app.yml -l pg-mongo
# Endpoint: mongodb://mongod:DBUser.Mongo@10.10.10.4:27017/
#--------------------------------------------------------------------------#
# pg-mongo:
# hosts:
# 10.10.10.11: { pg_seq: 1, pg_role: primary, vip_role: master }
# 10.10.10.12: { pg_seq: 2, pg_role: replica, vip_role: backup }
# 10.10.10.13: { pg_seq: 3, pg_role: replica, vip_role: backup }
# vars:
# pg_cluster: pg-mongo
# node_cluster: pg-mongo
# pg_users:
# - { name: mongod, password: DBUser.Mongo, superuser: true, comment: FerretDB backend user }
# pg_databases:
# - { name: postgres, extensions: [ documentdb, postgis, vector, pg_cron, rum ] }
# pg_hba_rules:
# - { user: all, db: all, addr: localhost, order: 1, auth: trust, title: 'documentdb localhost trust access' }
# - { user: all, db: all, addr: local, order: 1, auth: trust, title: 'documentdb local trust access' }
# - { user: mongod, db: postgres, addr: intra, order: 800, auth: pwd, title: 'ferretdb intranet access with password' }
# pg_parameters: { cron.database_name: postgres }
# pg_extensions: [ documentdb, postgis, pgvector, pg_cron, rum ]
# pg_libs: 'pg_documentdb, pg_documentdb_core, pg_documentdb_extended_rum, pg_cron, pg_stat_statements, auto_explain'
# pg_crontab:
# - '00 01 * * 1 /pg/bin/pg-backup full'
# - '00 01 * * 2,3,4,5,6,7 /pg/bin/pg-backup'
#
# # FerretDB Docker cluster and HAProxy service
# docker_enabled: true
# app: ferretdb
# apps:
# ferretdb:
# conf:
# FERRETDB_IMAGE: ghcr.io/ferretdb/ferretdb:2.7.0
# FERRETDB_POSTGRESQL_URL: 'postgres://mongod:DBUser.Mongo@host.docker.internal:5436/postgres?pool_min_conns=1&pool_max_conns=20'
# FERRETDB_BIND_ADDR: '{{ inventory_hostname }}'
# FERRETDB_PORT: 27018
# FERRETDB_LISTEN_ADDR: ':27017'
# FERRETDB_AUTH: true
# FERRETDB_TELEMETRY: disabled
#
# # HA Mongo endpoint: mongo.pigsty / 10.10.10.4:27017
# vip_enabled: true
# vip_vrid: 27
# vip_address: 10.10.10.4
# vip_preempt: false
# haproxy_services:
# - name: mongo
# port: 27017
# protocol: tcp
# balance: leastconn
# options:
# - option tcp-check
# servers:
# - { name: ferretdb-1, ip: 10.10.10.11, port: 27018, options: 'check port 27018' }
# - { name: ferretdb-2, ip: 10.10.10.12, port: 27018, options: 'check port 27018' }
# - { name: ferretdb-3, ip: 10.10.10.13, port: 27018, options: 'check port 27018' }
vars: # global variables
#----------------------------------------------#
# INFRA : https://pigsty.io/docs/infra/param
#----------------------------------------------#
version: v4.5.0 # pigsty version string
admin_ip: 10.10.10.10 # admin node ip address
region: default # upstream mirror region: default,china,europe
infra_portal: # infra services exposed via portal
home : { domain: i.pigsty } # default domain name
#----------------------------------------------#
# NODE : https://pigsty.io/docs/node/param
#----------------------------------------------#
nodename_overwrite: false # do not overwrite node hostname
node_repo_modules: node,infra,pgsql # install from upstream repo directly
node_tune: oltp # node tuning specs: oltp,olap,tiny,crit
#----------------------------------------------#
# PGSQL : https://pigsty.io/docs/pgsql/param
#----------------------------------------------#
pg_version: 18 # default postgres version (16,17,18)
pg_conf: oltp.yml # pgsql tuning specs: {oltp,olap,tiny,crit}.yml
#----------------------------------------------#
# PASSWORD : https://pigsty.io/docs/setup/security/
#----------------------------------------------#
grafana_admin_password: pigsty
grafana_view_password: DBUser.Viewer
pg_admin_password: DBUser.DBA
pg_monitor_password: DBUser.Monitor
pg_replication_password: DBUser.Replicator
patroni_password: Patroni.API
haproxy_admin_password: pigsty
minio_secret_key: S3User.MinIO
etcd_root_password: Etcd.Root
...
FerretDB 参数是 apps.ferretdb.conf 下的普通 APP 覆盖项:
app: ferretdb
apps:
ferretdb:
conf:
FERRETDB_IMAGE: ghcr.io/ferretdb/ferretdb:2.7.0
FERRETDB_POSTGRESQL_URL: 'postgres://mongod:DBUser.Mongo@host.docker.internal:5436/postgres'
FERRETDB_BIND_ADDR: 127.0.0.1
FERRETDB_PORT: 27017
FERRETDB_AUTH: true
FERRETDB_TELEMETRY: disabled
后端集群统一使用标准 PostgreSQL 参数、剧本、仪表盘和管理流程;不再存在 mongo_* 参数组或独立的 mongo.yml 剧本。
可选高可用拓扑
模板中保留了注释状态的三节点 pg-mongo 示例。需要时取消该区块以及两个额外 etcd 成员的注释即可。
HA 模式下,每个 FerretDB 容器绑定 {{ inventory_hostname }}:27018,HAProxy 通过浮动端点 10.10.10.4:27017(mongo.pigsty)暴露三个后端。PostgreSQL 故障转移仍由 Patroni 负责,FerretDB 始终保持无状态。
注意事项
- 模板包含方便开发测试的 HBA 示例,生产环境请收紧。
- 默认未启用客户端 MongoDB TLS。
- 后端使用标准 PostgreSQL 与 Docker 仪表盘监控;不再提供独立 FERRET 模块或模块仪表盘。
- FerretDB 或 DocumentDB 升级后应重新执行一次带认证的 CRUD 冒烟测试。