app/discourse
使用 Pigsty 托管的 PostgreSQL 部署 Discourse 社区论坛,应用容器内嵌 Redis
app/discourse 配置模板提供 Discourse 社区论坛的单节点参考配置:PostgreSQL 由 Pigsty 托管,Redis 内嵌在应用容器中,经 Pigsty Nginx 与 Unix Socket 对外提供服务。
该模板在 v4.5.0 发布后加入,需配套同版本的 app/discourse/ 与 files/discourse.sql,不能只复制下方 YAML。
更多细节,请参考 Discourse 部署教程
配置概览
- 配置名称:
app/discourse - 节点数量: 单节点
- 配置说明:使用 Pigsty 托管的 PostgreSQL 部署 Discourse 论坛,Redis 内嵌在应用容器中
- 适用系统:
el8, el9, el10, d12, d13, u22, u24, u26 - 适用架构:
x86_64(上游 Launcher 将 ARM64 支持描述为实验性) - 相关配置:
app/odoo、app/mattermost
启用方式:
./configure -c app/discourse [-i <primary_ip>]
vi pigsty.yml # 修改密码、域名与 SMTP
./deploy.yml
./docker.yml
./app.yml -l discourse
配置内容
源文件地址:pigsty/conf/app/discourse.yml
---
#==============================================================#
# File : discourse.yml
# Desc : Pigsty Discourse with external PostgreSQL / embedded Redis
# Ctime : 2026-10-14
# Mtime : 2026-10-14
# License : Apache-2.0 @ https://pigsty.io/docs/about/license/
# Copyright : 2018-2026 Ruohang Feng / Vonng (rh@vonng.com)
#==============================================================#
# Fresh host: ./configure -c app/discourse; edit pigsty.yml (passwords + SMTP)
# ./deploy.yml; ./docker.yml; ./app.yml -l discourse
# Existing Pigsty: merge the app/user/database/portal sections; do NOT replace
# the running inventory or initialize an existing PostgreSQL cluster again.
# ask.pigsty -> Pigsty Nginx :80/:443 -> Unix socket -> Discourse + Redis.
all:
children:
discourse:
hosts: { 10.10.10.10: {} }
vars:
app: discourse
apps:
discourse:
dest: /data/app/discourse
file:
- { path: /data/app/discourse ,state: directory ,mode: '0755' }
- { path: /data/app/discourse/shared ,state: directory ,mode: '0755' }
- { path: /data/app/discourse/shared/log/var-log ,state: directory ,mode: '0755' }
conf:
DISCOURSE_DATA: /data/app/discourse
DISCOURSE_HOSTNAME: ask.pigsty
DISCOURSE_VERSION: tests-passed
DISCOURSE_DOCKER_REF: 945d491ee62ac0d6e5d9076c173073c3f795d978
PG_HOST: 10.10.10.10
PG_PORT: 5432
PG_DBNAME: discourse
PG_USERNAME: discourse
PG_PASSWORD: DBUser.Discourse
UNICORN_WORKERS: 2
UNICORN_SIDEKIQS: 1
DISCOURSE_SIDEKIQ_WORKERS: 5
DISCOURSE_DB_POOL: 8
REDIS_MAX_MEMORY: 512mb
DISCOURSE_FORCE_HTTPS: false # set true with a trusted HTTPS portal
DISCOURSE_DEVELOPER_EMAILS: admin@example.com # CHANGE ME
DISCOURSE_SMTP_ADDRESS: smtp.example.com # CHANGE ME
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: ''
DISCOURSE_SMTP_PASSWORD: ''
DISCOURSE_SMTP_ENABLE_START_TLS: true
DISCOURSE_SMTP_FORCE_TLS: false
DISCOURSE_NOTIFICATION_EMAIL: noreply@example.com # CHANGE ME
pg-discourse:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-discourse
pg_extensions: [ pgvector ]
pg_users:
- name: discourse
password: DBUser.Discourse # CHANGE ME, same as PG_PASSWORD above
pgbouncer: false
roles: [{ name: dbrole_admin, state: revoke }]
comment: Discourse database owner
pg_databases:
- name: discourse
owner: discourse
encoding: UTF8
revokeconn: true
pgbouncer: false
baseline: discourse.sql
extensions: [ hstore, pg_trgm, unaccent, vector ]
comment: Discourse forum
pg_hba_rules:
- { user: discourse ,db: discourse ,addr: 172.16.0.0/12 ,auth: pwd ,title: 'Discourse from local Docker bridges' }
pg_crontab: [ '00 01 * * * /pg/bin/pg-backup full' ]
infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }
etcd: { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
vars:
version: v4.5.0
admin_ip: 10.10.10.10
region: default
node_tune: oltp
pg_conf: oltp.yml
pg_version: 18
docker_enabled: true
repo_enabled: false
node_repo_modules: node,infra,pgsql
node_etc_hosts: ['${admin_ip} i.pigsty ask.pigsty']
infra_portal:
home: { domain: i.pigsty }
discourse:
domain: ask.pigsty
endpoint: unix:/data/app/discourse/shared/nginx.http.sock
websocket: true
config: |
client_max_body_size 10m;
# CHANGE these demo credentials before any public deployment.
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
etcd_root_password: Etcd.Root
...
配置解读
此单节点模板使用官方经典 Launcher 在本地构建 Discourse 镜像,由 Docker Compose 运行,PostgreSQL 由 Pigsty 管理。
关键特性:
apps.discourse.dest 为 /data/app/discourse,管理文件与 shared/ 下的持久化数据位于同一目录DISCOURSE_DOCKER_REF 固定 Launcher 提交,DISCOURSE_VERSION 默认跟随官方 tests-passed 通道- 独立的
pg-discourse 集群使用 PostgreSQL 18,安装 pgvector;discourse 数据库启用 hstore、pg_trgm、unaccent、vector 扩展,并应用 discourse.sql 基线 discourse 用户撤销 dbrole_admin,用户与数据库均不接入 PgBouncer- HBA 只允许
discourse 用户从 172.16.0.0/12 Docker 网段访问 discourse 数据库 - Nginx 门户
ask.pigsty 转发到 unix:/data/app/discourse/shared/nginx.http.sock,启用 WebSocket,并设置 client_max_body_size 10m - 内嵌 Redis 的内存上限为
REDIS_MAX_MEMORY: 512mb - 每天凌晨 1 点执行一次全量备份
访问方式:
模板通过 node_etc_hosts 在本机将 ask.pigsty 解析到管理节点;其他客户端需自行将该域名解析到 Nginx 主机。
注意事项:
- 部署前修改
PG_PASSWORD 与 pg_users 中的密码(两处保持一致),以及管理员邮箱与 SMTP 参数;示例 SMTP 主机会使构建失败 - 公开部署使用真实域名与可信证书,并设置
DISCOURSE_FORCE_HTTPS: true - Discourse 使用 advisory lock,需直连 PostgreSQL,不能使用 PgBouncer 事务池;高可用部署改用只指向主库的直连入口
- 已有 Pigsty 环境只合并应用、用户、数据库与门户定义,不要重新运行
configure 或重复初始化集群 - Redis 持久化需要
vm.overcommit_memory=1,而 node_tune: oltp 对应的 Tuned 配置为 0,模板尚未处理,需自行配置持久化覆盖
感谢反馈,我们会据此改进这篇文档。
哪里没有解决?(可选)