Deploy Discourse with Pigsty-managed PostgreSQL and Redis embedded in the application container
The app/discourse template provides a single-node Discourse forum. Pigsty manages PostgreSQL, while Redis runs inside the application container. Pigsty Nginx serves Discourse through a Unix socket.
This template was added after v4.5.0. Use the matching app/discourse/ directory and files/discourse.sql from the same checkout; the YAML alone is not sufficient.
---#==============================================================## 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 ([email protected])#==============================================================## 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:discourseapps:discourse:dest:/data/app/discoursefile:- {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/discourseDISCOURSE_HOSTNAME:ask.pigstyDISCOURSE_VERSION:tests-passedDISCOURSE_DOCKER_REF:945d491ee62ac0d6e5d9076c173073c3f795d978PG_HOST:10.10.10.10PG_PORT:5432PG_DBNAME:discoursePG_USERNAME:discoursePG_PASSWORD:DBUser.DiscourseUNICORN_WORKERS:2UNICORN_SIDEKIQS:1DISCOURSE_SIDEKIQ_WORKERS:5DISCOURSE_DB_POOL:8REDIS_MAX_MEMORY:512mbDISCOURSE_FORCE_HTTPS:false# set true with a trusted HTTPS portalDISCOURSE_DEVELOPER_EMAILS:[email protected]# CHANGE MEDISCOURSE_SMTP_ADDRESS:smtp.example.com # CHANGE MEDISCOURSE_SMTP_PORT:587DISCOURSE_SMTP_USER_NAME:''DISCOURSE_SMTP_PASSWORD:''DISCOURSE_SMTP_ENABLE_START_TLS:trueDISCOURSE_SMTP_FORCE_TLS:falseDISCOURSE_NOTIFICATION_EMAIL:[email protected]# CHANGE MEpg-discourse:hosts:{10.10.10.10:{pg_seq:1, pg_role:primary } }vars:pg_cluster:pg-discoursepg_extensions:[pgvector ]pg_users:- name:discoursepassword:DBUser.Discourse # CHANGE ME, same as PG_PASSWORD abovepgbouncer:falseroles:[{name:dbrole_admin, state:revoke }]comment:Discourse database ownerpg_databases:- name:discourseowner:discourseencoding:UTF8revokeconn:truepgbouncer:falsebaseline:discourse.sqlextensions:[hstore, pg_trgm, unaccent, vector ]comment:Discourse forumpg_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.0admin_ip:10.10.10.10region:defaultnode_tune:oltppg_conf:oltp.ymlpg_version:18docker_enabled:truerepo_enabled:falsenode_repo_modules:node,infra,pgsqlnode_etc_hosts:['${admin_ip} i.pigsty ask.pigsty']infra_portal:home:{domain:i.pigsty }discourse:domain:ask.pigstyendpoint:unix:/data/app/discourse/shared/nginx.http.sockwebsocket:trueconfig:| client_max_body_size 10m;# CHANGE these demo credentials before any public deployment.grafana_admin_password:pigstygrafana_view_password:DBUser.Viewerpg_admin_password:DBUser.DBApg_monitor_password:DBUser.Monitorpg_replication_password:DBUser.Replicatorpatroni_password:Patroni.APIhaproxy_admin_password:pigstyetcd_root_password:Etcd.Root...
Explanation
The template builds the Discourse image locally with the official classic Launcher and runs it with Docker Compose, using PostgreSQL managed by Pigsty.
apps.discourse.dest is /data/app/discourse; managed files and persistent data under shared/ live in this directory.
DISCOURSE_DOCKER_REF pins the Launcher commit, while DISCOURSE_VERSION follows the upstream tests-passed channel by default.
The pg-discourse cluster uses PostgreSQL 18 and installs pgvector. The discourse database enables hstore, pg_trgm, unaccent, and vector, and applies the discourse.sql baseline.
The discourse user has dbrole_admin revoked. Neither the user nor the database uses PgBouncer.
The application HBA rule allows the discourse user to reach the discourse database from Docker networks in 172.16.0.0/12.
The ask.pigsty Nginx portal forwards to unix:/data/app/discourse/shared/nginx.http.sock, enables WebSocket, and sets client_max_body_size 10m.
Embedded Redis has a REDIS_MAX_MEMORY: 512mb limit.
A full PostgreSQL backup runs daily at 01:00.
Access the forum at http://ask.pigsty. The template adds this name to the local hosts file through node_etc_hosts; other clients need DNS or hosts entries pointing to the Nginx host.
Notes
Change PG_PASSWORD and the password in pg_users together. Configure the administrator email and SMTP settings; the sample SMTP hostname will cause the image build to fail.
For public access, use a real domain and trusted certificate, and set DISCOURSE_FORCE_HTTPS: true.
Discourse uses advisory locks and requires a direct PostgreSQL connection. Do not use PgBouncer transaction pooling. For HA, choose a direct service that routes only to the primary.
In an existing Pigsty environment, merge the application, user, database, and portal definitions. Do not rerun configure or reinitialize an existing cluster.
Redis persistence needs vm.overcommit_memory=1. The Tuned profile selected by node_tune: oltp uses 0; configure a persistent override before enabling Redis persistence.