# PostgreSQL Mongo 模式

> 使用 DocumentDB 与 FerretDB Docker APP，让 PostgreSQL 提供 MongoDB 协议兼容能力。

---

LLMS index: [llms.txt](/llms.txt)

---

`mongo` 配置模板是一个 **PostgreSQL 部署模式**，而不是独立的 Pigsty 模块。它由以下组件组成：

- 由标准 `PGSQL` 模块管理的 PostgreSQL 18
- `documentdb` 扩展及其预加载库
- 通过 Pigsty Docker APP 工作流部署的无状态 FerretDB 代理

所有数据、高可用、备份、监控与生命周期管理仍由 PostgreSQL 负责；FerretDB 只提供 MongoDB 线协议兼容端点。


--------

## 快速开始

模板默认部署在单节点 `10.10.10.10` 上，FerretDB 默认只监听本机回环地址。

如果尚未安装 `mongosh`，请单独安装，或使用其他兼容 MongoDB 协议的客户端。

```bash
./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`。


--------

## 配置

源文件：[`pigsty/conf/mongo.yml`](https://github.com/pgsty/pigsty/blob/main/conf/mongo.yml)

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#==============================================================#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># File      :   mongo.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># Desc      :   PostgreSQL Mongo Mode (DocumentDB + FerretDB)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># Ctime     :   2025-02-23</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># Mtime     :   2026-08-05</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># Docs      :   https://pigsty.io/docs/conf/mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># License   :   Apache-2.0 @ https://pigsty.io/docs/about/license/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># Copyright :   2018-2026  Ruohang Feng / Vonng (rh@vonng.com)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#==============================================================#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># This is the PostgreSQL Mongo mode template, powered by DocumentDB + FerretDB</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># It provides a MongoDB wire-compatible endpoint backed by PostgreSQL</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># This config template works with PostgreSQL 16, 17, 18</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># tutorial: https://pigsty.io/docs/conf/mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># Usage:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   curl https://repo.pigsty.io/get | bash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   ./configure -c mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   ./deploy.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   ./docker.yml -l pg-meta</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   ./app.yml -l pg-meta</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   # install mongosh separately if it is not already available</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#   mongosh &#39;mongodb://mongod:DBUser.Mongo@127.0.0.1:27017/&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">all</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">children</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">infra</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">10.10.10.10</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">infra_seq</span><span class="p">:</span><span class="w"> </span><span class="nt">1 }} ,vars</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">repo_enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span>}}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">etcd</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">10.10.10.10</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">etcd_seq</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#10.10.10.11: { etcd_seq: 2 }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#10.10.10.12: { etcd_seq: 3 }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">vars</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">etcd_cluster</span><span class="p">:</span><span class="w"> </span><span class="l">etcd }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#minio: { hosts: { 10.10.10.10: { minio_seq: 1 }} ,vars: { minio_cluster: minio }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># PGSQL Database Cluster</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pg-meta</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">10.10.10.10</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">pg_seq</span><span class="p">:</span><span class="w"> </span><span class="nt">1, pg_role</span><span class="p">:</span><span class="w"> </span><span class="l">primary }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">vars</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_cluster</span><span class="p">:</span><span class="w"> </span><span class="l">pg-meta</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_users</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="nt">mongod      ,password</span><span class="p">:</span><span class="w"> </span><span class="nt">DBUser.Mongo  ,superuser</span><span class="p">:</span><span class="w"> </span><span class="nt">true  ,comment</span><span class="p">:</span><span class="w"> </span><span class="l">FerretDB backend user }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="nt">dbuser_meta ,password</span><span class="p">:</span><span class="w"> </span><span class="nt">DBUser.Meta   ,pgbouncer</span><span class="p">:</span><span class="w"> </span><span class="nt">true ,roles</span><span class="p">:</span><span class="w"> </span><span class="nt">[dbrole_admin   ] ,comment</span><span class="p">:</span><span class="w"> </span><span class="l">pigsty admin user }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="nt">dbuser_view ,password</span><span class="p">:</span><span class="w"> </span><span class="nt">DBUser.Viewer ,pgbouncer</span><span class="p">:</span><span class="w"> </span><span class="nt">true ,roles</span><span class="p">:</span><span class="w"> </span><span class="nt">[dbrole_readonly] ,comment</span><span class="p">:</span><span class="w"> </span><span class="l">read-only viewer  }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_databases</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="nt">postgres, extensions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="l">documentdb, postgis, vector, pg_cron, rum ]} </span><span class="w"> </span><span class="c"># run on the postgres database</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_hba_rules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="nt">dbuser_view , db</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,addr</span><span class="p">:</span><span class="w"> </span><span class="nt">infra ,auth</span><span class="p">:</span><span class="w"> </span><span class="nt">pwd ,title</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;allow grafana dashboard access cmdb from infra nodes&#39;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="c"># WARNING: demo/dev only. Avoid world access for dbsu in production.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="nt">postgres    , db</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,addr</span><span class="p">:</span><span class="w"> </span><span class="nt">world ,auth</span><span class="p">:</span><span class="w"> </span><span class="nt">pwd ,title</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;dbsu password access everywhere&#39;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,db</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,addr</span><span class="p">:</span><span class="w"> </span><span class="nt">localhost ,order</span><span class="p">:</span><span class="w"> </span><span class="nt">1  ,auth</span><span class="p">:</span><span class="w"> </span><span class="nt">trust ,title</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;documentdb localhost trust access&#39;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,db</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,addr</span><span class="p">:</span><span class="w"> </span><span class="nt">local     ,order</span><span class="p">:</span><span class="w"> </span><span class="nt">1  ,auth</span><span class="p">:</span><span class="w"> </span><span class="nt">trust ,title</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;documentdb local     trust access&#39;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- {<span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,db</span><span class="p">:</span><span class="w"> </span><span class="nt">all ,addr</span><span class="p">:</span><span class="w"> </span><span class="nt">intra ,auth</span><span class="p">:</span><span class="w"> </span><span class="nt">pwd ,title</span><span class="p">:</span><span class="w"> </span><span class="nt">&#39;everyone intranet access with password&#39; ,order</span><span class="p">:</span><span class="w"> </span><span class="m">800</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_parameters</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">cron.database_name</span><span class="p">:</span><span class="w"> </span><span class="l">postgres }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_extensions</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="l">documentdb, postgis, pgvector, pg_cron, rum ]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_libs</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;pg_documentdb, pg_documentdb_core, pg_documentdb_extended_rum, pg_cron, pg_stat_statements, auto_explain&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">pg_crontab</span><span class="p">:</span><span class="w">     </span><span class="c"># https://pigsty.io/docs/pgsql/admin/crontab</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="s1">&#39;00 01 * * * /pg/bin/pg-backup full&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># FerretDB Docker APP on the same node, exposed at 127.0.0.1:27017</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">docker_enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">ferretdb</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">apps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">ferretdb</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">conf</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_IMAGE</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/ferretdb/ferretdb:2.7.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_POSTGRESQL_URL</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;postgres://mongod:DBUser.Mongo@host.docker.internal:5436/postgres?pool_min_conns=1&amp;pool_max_conns=20&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_BIND_ADDR</span><span class="p">:</span><span class="w"> </span><span class="m">127.0.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_PORT</span><span class="p">:</span><span class="w"> </span><span class="m">27017</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_LISTEN_ADDR</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;:27017&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_AUTH</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">FERRETDB_TELEMETRY</span><span class="p">:</span><span class="w"> </span><span class="l">disabled</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#--------------------------------------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># OPTIONAL: Three-node PostgreSQL + DocumentDB + FerretDB HA cluster</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Uncomment this entire block and the two additional etcd members above.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Then run: ./docker.yml -l pg-mongo &amp;&amp; ./app.yml -l pg-mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Endpoint: mongodb://mongod:DBUser.Mongo@10.10.10.4:27017/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#--------------------------------------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># pg-mongo:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#   hosts:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     10.10.10.11: { pg_seq: 1, pg_role: primary, vip_role: master }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     10.10.10.12: { pg_seq: 2, pg_role: replica, vip_role: backup }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     10.10.10.13: { pg_seq: 3, pg_role: replica, vip_role: backup }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#   vars:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_cluster: pg-mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     node_cluster: pg-mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_users:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - { name: mongod, password: DBUser.Mongo, superuser: true, comment: FerretDB backend user }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_databases:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - { name: postgres, extensions: [ documentdb, postgis, vector, pg_cron, rum ] }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_hba_rules:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - { user: all, db: all, addr: localhost, order: 1, auth: trust, title: &#39;documentdb localhost trust access&#39; }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - { user: all, db: all, addr: local, order: 1, auth: trust, title: &#39;documentdb local trust access&#39; }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - { user: mongod, db: postgres, addr: intra, order: 800, auth: pwd, title: &#39;ferretdb intranet access with password&#39; }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_parameters: { cron.database_name: postgres }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_extensions: [ documentdb, postgis, pgvector, pg_cron, rum ]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_libs: &#39;pg_documentdb, pg_documentdb_core, pg_documentdb_extended_rum, pg_cron, pg_stat_statements, auto_explain&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     pg_crontab:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - &#39;00 01 * * 1 /pg/bin/pg-backup full&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - &#39;00 01 * * 2,3,4,5,6,7 /pg/bin/pg-backup&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     # FerretDB Docker cluster and HAProxy service</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     docker_enabled: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     app: ferretdb</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     apps:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       ferretdb:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#         conf:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_IMAGE: ghcr.io/ferretdb/ferretdb:2.7.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_POSTGRESQL_URL: &#39;postgres://mongod:DBUser.Mongo@host.docker.internal:5436/postgres?pool_min_conns=1&amp;pool_max_conns=20&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_BIND_ADDR: &#39;{{ inventory_hostname }}&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_PORT: 27018</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_LISTEN_ADDR: &#39;:27017&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_AUTH: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           FERRETDB_TELEMETRY: disabled</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     # HA Mongo endpoint: mongo.pigsty / 10.10.10.4:27017</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     vip_enabled: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     vip_vrid: 27</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     vip_address: 10.10.10.4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     vip_preempt: false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#     haproxy_services:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#       - name: mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#         port: 27017</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#         protocol: tcp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#         balance: leastconn</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#         options:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           - option tcp-check</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#         servers:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           - { name: ferretdb-1, ip: 10.10.10.11, port: 27018, options: &#39;check port 27018&#39; }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           - { name: ferretdb-2, ip: 10.10.10.12, port: 27018, options: &#39;check port 27018&#39; }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#           - { name: ferretdb-3, ip: 10.10.10.13, port: 27018, options: &#39;check port 27018&#39; }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">vars</span><span class="p">:</span><span class="w">                               </span><span class="c"># global variables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># INFRA : https://pigsty.io/docs/infra/param</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="l">v4.5.0                  </span><span class="w"> </span><span class="c"># pigsty version string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">admin_ip</span><span class="p">:</span><span class="w"> </span><span class="m">10.10.10.10</span><span class="w">             </span><span class="c"># admin node ip address</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">region</span><span class="p">:</span><span class="w"> </span><span class="l">default                  </span><span class="w"> </span><span class="c"># upstream mirror region: default,china,europe</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">infra_portal</span><span class="p">:</span><span class="w">                     </span><span class="c"># infra services exposed via portal</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">home </span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">domain</span><span class="p">:</span><span class="w"> </span><span class="l">i.pigsty }    </span><span class="w"> </span><span class="c"># default domain name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># NODE : https://pigsty.io/docs/node/param</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodename_overwrite</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">           </span><span class="c"># do not overwrite node hostname</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">node_repo_modules</span><span class="p">:</span><span class="w"> </span><span class="l">node,infra,pgsql</span><span class="w"> </span><span class="c"># install from upstream repo directly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">node_tune</span><span class="p">:</span><span class="w"> </span><span class="l">oltp                    </span><span class="w"> </span><span class="c"># node tuning specs: oltp,olap,tiny,crit</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># PGSQL : https://pigsty.io/docs/pgsql/param</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pg_version</span><span class="p">:</span><span class="w"> </span><span class="m">18</span><span class="w">                      </span><span class="c"># default postgres version (16,17,18)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pg_conf</span><span class="p">:</span><span class="w"> </span><span class="l">oltp.yml                  </span><span class="w"> </span><span class="c"># pgsql tuning specs: {oltp,olap,tiny,crit}.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># PASSWORD : https://pigsty.io/docs/setup/security/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#----------------------------------------------#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">grafana_admin_password</span><span class="p">:</span><span class="w"> </span><span class="l">pigsty</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">grafana_view_password</span><span class="p">:</span><span class="w"> </span><span class="l">DBUser.Viewer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pg_admin_password</span><span class="p">:</span><span class="w"> </span><span class="l">DBUser.DBA</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pg_monitor_password</span><span class="p">:</span><span class="w"> </span><span class="l">DBUser.Monitor</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pg_replication_password</span><span class="p">:</span><span class="w"> </span><span class="l">DBUser.Replicator</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">patroni_password</span><span class="p">:</span><span class="w"> </span><span class="l">Patroni.API</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">haproxy_admin_password</span><span class="p">:</span><span class="w"> </span><span class="l">pigsty</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">minio_secret_key</span><span class="p">:</span><span class="w"> </span><span class="l">S3User.MinIO</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">etcd_root_password</span><span class="p">:</span><span class="w"> </span><span class="l">Etcd.Root</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">...</span><span class="w">
</span></span></span></code></pre></div>

FerretDB 参数是 `apps.ferretdb.conf` 下的普通 APP 覆盖项：

```yaml
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_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 冒烟测试。
