From b2bf966e86d85fb1944a02f282e6de364a6b9c86 Mon Sep 17 00:00:00 2001
From: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com>
Date: Mon, 22 Jun 2026 14:33:35 +0400
Subject: [PATCH 1/3] feat: add Zulip template
---
blueprints/zulip/docker-compose.yml | 113 ++++++++++++++++++++++++++++
blueprints/zulip/template.toml | 20 +++++
blueprints/zulip/zulip.svg | 6 ++
meta.json | 18 +++++
4 files changed, 157 insertions(+)
create mode 100644 blueprints/zulip/docker-compose.yml
create mode 100644 blueprints/zulip/template.toml
create mode 100644 blueprints/zulip/zulip.svg
diff --git a/blueprints/zulip/docker-compose.yml b/blueprints/zulip/docker-compose.yml
new file mode 100644
index 00000000..e8415255
--- /dev/null
+++ b/blueprints/zulip/docker-compose.yml
@@ -0,0 +1,113 @@
+version: "3.8"
+
+services:
+ database:
+ image: zulip/zulip-postgresql:14
+ restart: unless-stopped
+ secrets:
+ - zulip__postgres_password
+ environment:
+ POSTGRES_DB: zulip
+ POSTGRES_USER: zulip
+ POSTGRES_PASSWORD_FILE: /run/secrets/zulip__postgres_password
+ volumes:
+ - zulipPostgresData:/var/lib/postgresql/data
+
+ memcached:
+ image: memcached:alpine
+ restart: unless-stopped
+ command:
+ - sh
+ - -euc
+ - |
+ echo 'mech_list: plain' > "$$SASL_CONF_PATH"
+ echo "zulip@$$HOSTNAME:$$(cat $$MEMCACHED_PASSWORD_FILE)" > "$$MEMCACHED_SASL_PWDB"
+ echo "zulip@localhost:$$(cat $$MEMCACHED_PASSWORD_FILE)" >> "$$MEMCACHED_SASL_PWDB"
+ exec memcached -S
+ secrets:
+ - zulip__memcached_password
+ environment:
+ SASL_CONF_PATH: /home/memcache/memcached.conf
+ MEMCACHED_SASL_PWDB: /home/memcache/memcached-sasl-db
+ MEMCACHED_PASSWORD_FILE: /run/secrets/zulip__memcached_password
+
+ rabbitmq:
+ image: rabbitmq:4.2
+ restart: unless-stopped
+ command:
+ - sh
+ - -euc
+ - |
+ export RABBITMQ_DEFAULT_PASS="$$(cat $$RABBITMQ_PASSWORD_FILE)"
+ echo "default_user = $$RABBITMQ_DEFAULT_USER" >> /etc/rabbitmq/rabbitmq.conf
+ echo "default_pass = $$RABBITMQ_DEFAULT_PASS" >> /etc/rabbitmq/rabbitmq.conf
+ exec docker-entrypoint.sh rabbitmq-server
+ secrets:
+ - zulip__rabbitmq_password
+ environment:
+ RABBITMQ_DEFAULT_USER: zulip
+ RABBITMQ_PASSWORD_FILE: /run/secrets/zulip__rabbitmq_password
+ volumes:
+ - zulipRabbitmqData:/var/lib/rabbitmq
+
+ redis:
+ image: redis:alpine
+ restart: unless-stopped
+ command:
+ - sh
+ - -euc
+ - /usr/local/bin/docker-entrypoint.sh --requirepass "$$(cat $$REDIS_PASSWORD_FILE)"
+ secrets:
+ - zulip__redis_password
+ environment:
+ REDIS_PASSWORD_FILE: /run/secrets/zulip__redis_password
+ volumes:
+ - zulipRedisData:/data
+
+ zulip:
+ image: ghcr.io/zulip/zulip-server:12.0-1
+ restart: unless-stopped
+ depends_on:
+ - database
+ - memcached
+ - rabbitmq
+ - redis
+ secrets:
+ - zulip__postgres_password
+ - zulip__memcached_password
+ - zulip__rabbitmq_password
+ - zulip__redis_password
+ - zulip__secret_key
+ environment:
+ SETTING_EXTERNAL_HOST: ${ZULIP_EXTERNAL_HOST}
+ SETTING_ZULIP_ADMINISTRATOR: ${ZULIP_ADMINISTRATOR}
+ SETTING_REMOTE_POSTGRES_HOST: database
+ SETTING_MEMCACHED_LOCATION: memcached:11211
+ SETTING_RABBITMQ_HOST: rabbitmq
+ SETTING_REDIS_HOST: redis
+ DISABLE_HTTPS: "True"
+ SSL_CERTIFICATE_GENERATION: self-signed
+ volumes:
+ - zulipData:/data
+ ulimits:
+ nofile:
+ soft: 1000000
+ hard: 1048576
+
+volumes:
+ zulipData:
+ zulipPostgresData:
+ zulipRabbitmqData:
+ zulipRedisData:
+
+secrets:
+ zulip__postgres_password:
+ environment: ZULIP_POSTGRES_PASSWORD
+ zulip__memcached_password:
+ environment: ZULIP_MEMCACHED_PASSWORD
+ zulip__rabbitmq_password:
+ environment: ZULIP_RABBITMQ_PASSWORD
+ zulip__redis_password:
+ environment: ZULIP_REDIS_PASSWORD
+ zulip__secret_key:
+ environment: ZULIP_SECRET_KEY
\ No newline at end of file
diff --git a/blueprints/zulip/template.toml b/blueprints/zulip/template.toml
new file mode 100644
index 00000000..f975978f
--- /dev/null
+++ b/blueprints/zulip/template.toml
@@ -0,0 +1,20 @@
+[variables]
+main_domain = "${domain}"
+admin_email = "${email}"
+
+[config]
+env = [
+ "ZULIP_EXTERNAL_HOST=${main_domain}",
+ "ZULIP_ADMINISTRATOR=${admin_email}",
+ "ZULIP_POSTGRES_PASSWORD=${password:32}",
+ "ZULIP_MEMCACHED_PASSWORD=${password:32}",
+ "ZULIP_RABBITMQ_PASSWORD=${password:32}",
+ "ZULIP_REDIS_PASSWORD=${password:32}",
+ "ZULIP_SECRET_KEY=${password:64}",
+]
+mounts = []
+
+[[config.domains]]
+serviceName = "zulip"
+port = 80
+host = "${main_domain}"
\ No newline at end of file
diff --git a/blueprints/zulip/zulip.svg b/blueprints/zulip/zulip.svg
new file mode 100644
index 00000000..6d53c774
--- /dev/null
+++ b/blueprints/zulip/zulip.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/meta.json b/meta.json
index 8be7825d..3cb4c246 100644
--- a/meta.json
+++ b/meta.json
@@ -6799,5 +6799,23 @@
"saml",
"multi-tenant"
]
+ },
+ {
+ "id": "zulip",
+ "name": "Zulip",
+ "version": "12.0-1",
+ "description": "Open-source threaded team chat designed to keep team communication organized and productive.",
+ "logo": "zulip.svg",
+ "links": {
+ "github": "https://github.com/zulip/docker-zulip",
+ "website": "https://zulip.com/",
+ "docs": "https://zulip.readthedocs.io/projects/docker/"
+ },
+ "tags": [
+ "chat",
+ "collaboration",
+ "team",
+ "self-hosted"
+ ]
}
]
From c69a2900f52e56ef9ebee994be33a6d7a06b157f Mon Sep 17 00:00:00 2001
From: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com>
Date: Tue, 7 Jul 2026 23:43:13 +0400
Subject: [PATCH 2/3] Update Zulip reverse proxy settings
---
blueprints/zulip/docker-compose.yml | 8 ++++----
blueprints/zulip/template.toml | 3 ++-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/blueprints/zulip/docker-compose.yml b/blueprints/zulip/docker-compose.yml
index e8415255..bf9ec636 100644
--- a/blueprints/zulip/docker-compose.yml
+++ b/blueprints/zulip/docker-compose.yml
@@ -65,7 +65,7 @@ services:
- zulipRedisData:/data
zulip:
- image: ghcr.io/zulip/zulip-server:12.0-1
+ image: ghcr.io/zulip/zulip-server:12.1-0
restart: unless-stopped
depends_on:
- database
@@ -85,8 +85,8 @@ services:
SETTING_MEMCACHED_LOCATION: memcached:11211
SETTING_RABBITMQ_HOST: rabbitmq
SETTING_REDIS_HOST: redis
- DISABLE_HTTPS: "True"
- SSL_CERTIFICATE_GENERATION: self-signed
+ CONFIG_application_server__http_only: "true"
+ TRUST_GATEWAY_IP: ${ZULIP_TRUST_GATEWAY_IP}
volumes:
- zulipData:/data
ulimits:
@@ -110,4 +110,4 @@ secrets:
zulip__redis_password:
environment: ZULIP_REDIS_PASSWORD
zulip__secret_key:
- environment: ZULIP_SECRET_KEY
\ No newline at end of file
+ environment: ZULIP_SECRET_KEY
diff --git a/blueprints/zulip/template.toml b/blueprints/zulip/template.toml
index f975978f..c10eebd6 100644
--- a/blueprints/zulip/template.toml
+++ b/blueprints/zulip/template.toml
@@ -11,10 +11,11 @@ env = [
"ZULIP_RABBITMQ_PASSWORD=${password:32}",
"ZULIP_REDIS_PASSWORD=${password:32}",
"ZULIP_SECRET_KEY=${password:64}",
+ "ZULIP_TRUST_GATEWAY_IP=True",
]
mounts = []
[[config.domains]]
serviceName = "zulip"
port = 80
-host = "${main_domain}"
\ No newline at end of file
+host = "${main_domain}"
From 56df57252272f2c52d99107e0997b032df8a2c12 Mon Sep 17 00:00:00 2001
From: Mauricio Siu
Date: Wed, 8 Jul 2026 01:24:58 -0600
Subject: [PATCH 3/3] fix: trust Dokploy's Traefik proxy via LOADBALANCER_IPS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Zulip 12 rejects requests forwarded by an untrusted reverse proxy with
a 500 "Proxy-Misconfiguration: Incorrect reverse proxy IPs set in
Zulip" error page. TRUST_GATEWAY_IP=True only whitelists the
container's default-route gateway IP, but Dokploy's Traefik connects
from its own container IP on the (dynamically-subnetted) compose
network, so it was never trusted.
Replace TRUST_GATEWAY_IP with LOADBALANCER_IPS covering the RFC1918
ranges, which Zulip feeds into nginx set_real_ip_from / its trusted
proxy list, so Traefik is trusted regardless of which Docker subnet it
connects from.
Also align meta.json version with the shipped image tag (12.1-0).
Note: the zulip-server image ships a HEALTHCHECK (/health, 300s start
period) and first boot runs full migrations, so Traefik only exposes
the router once the container turns healthy — expect several minutes
of 404 on the domain right after the first deploy.
Co-Authored-By: Claude Fable 5
---
blueprints/zulip/docker-compose.yml | 2 +-
blueprints/zulip/meta.json | 2 +-
blueprints/zulip/template.toml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/blueprints/zulip/docker-compose.yml b/blueprints/zulip/docker-compose.yml
index bf9ec636..8a33cfc8 100644
--- a/blueprints/zulip/docker-compose.yml
+++ b/blueprints/zulip/docker-compose.yml
@@ -86,7 +86,7 @@ services:
SETTING_RABBITMQ_HOST: rabbitmq
SETTING_REDIS_HOST: redis
CONFIG_application_server__http_only: "true"
- TRUST_GATEWAY_IP: ${ZULIP_TRUST_GATEWAY_IP}
+ LOADBALANCER_IPS: ${ZULIP_LOADBALANCER_IPS}
volumes:
- zulipData:/data
ulimits:
diff --git a/blueprints/zulip/meta.json b/blueprints/zulip/meta.json
index be96cd97..18b6a006 100644
--- a/blueprints/zulip/meta.json
+++ b/blueprints/zulip/meta.json
@@ -1,7 +1,7 @@
{
"id": "zulip",
"name": "Zulip",
- "version": "12.0-1",
+ "version": "12.1-0",
"description": "Open-source threaded team chat designed to keep team communication organized and productive.",
"logo": "zulip.svg",
"links": {
diff --git a/blueprints/zulip/template.toml b/blueprints/zulip/template.toml
index c10eebd6..821c66bd 100644
--- a/blueprints/zulip/template.toml
+++ b/blueprints/zulip/template.toml
@@ -11,7 +11,7 @@ env = [
"ZULIP_RABBITMQ_PASSWORD=${password:32}",
"ZULIP_REDIS_PASSWORD=${password:32}",
"ZULIP_SECRET_KEY=${password:64}",
- "ZULIP_TRUST_GATEWAY_IP=True",
+ "ZULIP_LOADBALANCER_IPS=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16",
]
mounts = []