Zulip 自托管部署方案评估:标准 installer、Docker 与 ChatArch 路径约束

Zulip Deployment Options And Architecture

Executive Summary

Zulip is self-hostable, unlike official Discord. It is also more structured than Discord/Revolt-style chat because Zulip’s core model is:

Organization -> Stream -> Topic -> Message

Every message belongs to a topic. This makes Zulip more rule/format oriented than Discord and more suitable for engineering/Agent workrooms. It is still a realtime team-chat system, not a Discourse-like long-form forum.

Deployment choice is less straightforward:

  • Zulip’s standard installer is the official/default production route and does not use Docker.
  • However, the standard installer expects a fresh/dedicated machine and configures system packages like nginx, PostgreSQL, Redis, RabbitMQ, and memcached. This conflicts with the user’s wish to keep all data/install state inside ChatArch paths on an existing multi-service host.
  • Zulip’s official Docker image is supported for organizations that prefer Docker, but Zulip docs say it moderately increases install/maintenance/upgrade effort compared with the standard installer.
  • For the existing zhihong.oray host, Docker/Compose is the cleanest way to contain all data under /home/zhihong/.chatarch/zulip/ and avoid touching the existing host nginx/PostgreSQL services.
  • If avoiding Docker is more important than path containment, the clean non-Docker option is a fresh dedicated VM/LXC/container-like host where Zulip can own the OS-level services.

User Questions

Is Zulip self-hostable?

Yes. Zulip is open-source and self-hostable. It also provides Zulip Cloud as a hosted SaaS option.

Is Zulip more rule/format structured?

Yes, compared with Discord/Revolt. Zulip forces a topic for every message:

Organization
  -> Stream
      -> Topic
          -> Message

This means discussions are naturally grouped by topic. It is less noisy than Discord-style channel chat and better for engineering/Agent workflows.

Compared with Discourse:

  • Discourse is more forum/document style: category → topic → posts, good for long-term public decisions and searchable discussions.
  • Zulip is more realtime chat style but with mandatory topic structure, good for internal working streams and fast Agent collaboration.

Does Zulip need another nginx if the system already has nginx?

With the standard non-Docker installer: yes, Zulip installs/configures nginx as part of its own service stack. Zulip’s docs say the installer expects Zulip to be the only thing running on the system and installs/configures packages like nginx, PostgreSQL, Redis, etc.

On this host, we already have a main nginx for ChatArch local/public services. Letting Zulip’s standard installer modify /etc/nginx directly on the same host is risky and against Zulip’s own guidance for existing servers.

With Docker/Compose: the Zulip container includes its own internal nginx/application routing. We can bind the container only to 127.0.0.1:<port> and keep host nginx as the only public ingress, which matches ChatArch service-entry rules.

Is Zulip’s SQL SQLite?

No. Zulip uses PostgreSQL for persistent data. It is not SQLite. PostgreSQL is a production database with much stronger concurrency, indexing, transactions, and replication support. Zulip also uses Redis, RabbitMQ, and memcached for realtime/cache/queue functions.

Zulip Backend Architecture

Official architecture docs describe these core components:

  • Python / Django: main web application server.
  • Tornado: realtime push / long-polling event delivery.
  • nginx: routes static files, app traffic, and realtime push endpoints.
  • Supervisor: manages application processes.
  • PostgreSQL: persistent database.
  • RabbitMQ: background job queue.
  • memcached: cache for model objects.
  • Redis: short-term data stores and rate limiting.

This is not a simple single Go/Node binary. Non-Docker deployment is possible and official, but it is a system-level installation.

Deployment Option A: Standard Zulip Installer

Status

Official/default production installation path.

Docs say you can install a self-hosted Zulip server on your own Ubuntu/Debian system using the standard installer.

Platform

Supported production operating systems include Ubuntu and Debian versions. Current docs mention Ubuntu 22.04/24.04/26.04 and Debian 12/13.

Install shape

Typical install flow:

curl -fLO https://download.zulip.com/server/zulip-server-latest.tar.gz
tar -xf zulip-server-latest.tar.gz
./zulip-server-*/scripts/setup/install --email=... --hostname=...

The installer sets key settings such as:

EXTERNAL_HOST
ZULIP_ADMINISTRATOR

Where data/config lands

Standard install uses system paths, including:

/etc/zulip/settings.py
/etc/zulip/zulip.conf
/home/zulip/deployments/current/
/home/zulip/prod-static/
/var/log/zulip/
PostgreSQL data under system PostgreSQL paths

Persistent uploaded files are local by default unless configured for S3-compatible storage.

Pros

  • Official/default production path.
  • No Docker.
  • Zulip says it is easier to install, maintain, and upgrade than Docker for most organizations.
  • Best fit for a fresh dedicated VM where Zulip can own the OS-level services.

Cons on current ChatArch host

  • It expects Zulip to be the only major app on the system.
  • It installs/configures nginx, PostgreSQL, Redis, RabbitMQ, memcached, supervisor, etc.
  • It may modify /etc/nginx and system service configuration.
  • It is hard to keep all data under /home/zhihong/.chatarch/zulip/.
  • Official docs warn that installing on a server already running other nginx/Django apps is not recommended.
  • No convenient uninstall process is documented.

Fit for user’s preference

Best fit for “no Docker” only if we allocate a dedicated VM/LXC/host.

Not ideal for this existing multi-service ChatArch host.

Deployment Option B: Official Docker Image / Docker Compose

Status

Official Docker image for production deployments that prefer containers.

The official Docker README says:

  • Built images are available from ghcr.io/zulip/zulip-server.
  • Current image version observed: 12.1-0.
  • Zulip recommends using Docker only if the organization prefers deploying services this way.
  • Docker moderately increases install, maintenance, and upgrade effort compared with the standard installer.

Compose components

Official compose includes:

zulip-server
PostgreSQL
memcached
RabbitMQ
Redis

The Zulip server image defaults to exposing SMTP/HTTP/HTTPS ports, so we must inspect and override the effective compose config before starting.

Data placement

Default compose uses named volumes:

zulip
postgresql-14
rabbitmq
redis

For ChatArch, we can change these to bind mounts under:

/home/zhihong/.chatarch/zulip/data/zulip
/home/zhihong/.chatarch/zulip/data/postgresql-14
/home/zhihong/.chatarch/zulip/data/rabbitmq
/home/zhihong/.chatarch/zulip/data/redis
/home/zhihong/.chatarch/zulip/secrets
/home/zhihong/.chatarch/zulip/config

Pros

  • Keeps all Zulip-related data/config/secrets under ChatArch service root.
  • Avoids Zulip modifying host /etc/nginx, host PostgreSQL, host RabbitMQ, etc.
  • Can bind only to 127.0.0.1:<port> and use existing ChatArch nginx local/public entry.
  • Safer for this existing server with Discourse/Gitea/Stoat/etc.
  • Easier to remove as a demo if we decide not to keep it.

Cons

  • User prefers avoiding Docker when possible.
  • Official docs say Docker moderately increases maintenance/upgrade effort compared with standard installer.
  • Need careful port override to avoid binding host 25/80/443 accidentally.
  • Still a multi-service stack.

Fit for user’s preference

Best fit for “keep everything inside ChatArch and don’t disturb existing host services”.

Deployment Option C: Fresh VM/LXC With Standard Installer

Status

This is the cleanest non-Docker architecture if the user wants no Docker but also does not want Zulip to alter the existing host.

Shape:

Host Nginx/local-public entry
    -> reverse proxy to dedicated Zulip VM/LXC IP:port
Dedicated Zulip VM/LXC
    -> standard Zulip installer owns its internal nginx/PostgreSQL/Redis/RabbitMQ/memcached

Pros

  • Uses Zulip’s default non-Docker production installer.
  • Avoids polluting the main host’s /etc/nginx, PostgreSQL, RabbitMQ, etc.
  • Matches official recommendation of a fresh/dedicated system.

Cons

  • Requires VM/LXC/proxmox/systemd-nspawn/lxd-style environment or another machine.
  • More infrastructure work before Zulip itself.
  • Data is inside that VM/container filesystem, not simply under /home/zhihong/.chatarch/zulip/ unless we intentionally mount a ChatArch directory into it.

Fit

Best long-term non-Docker option, but not fastest.

Deployment Option D: Source/Development Install

Status

Zulip’s source/development install is for hacking on Zulip, not production deployment.

Pros

  • Useful for development and understanding code.
  • Can run without Docker in a dev context.

Cons

  • Not a production deployment path.
  • More moving parts to supervise manually.
  • Not appropriate for a durable community service.

Recommendation For ChatArch

Given the user’s two constraints:

  1. Prefer not Docker if possible.
  2. Keep data/install location inside ChatArch internal paths.

The honest recommendation is:

If this is a quick inspectable demo on the existing zhihong.oray host

Use official Docker Compose, but with strict ChatArch containment:

/home/zhihong/.chatarch/zulip/
  compose/
  data/
  secrets/
  logs/
  backups/

Bind only a localhost port, e.g.:

127.0.0.1:3095 -> Zulip container HTTP

Expose via:

zulip.local.wzhecnu.cn -> 127.0.0.1:3095
zulip.public.wzhecnu.cn -> automatic public-entry -> local nginx

This avoids disrupting existing Nginx/Postgres/etc.

If this is meant to be a long-term production Zulip and Docker avoidance matters more

Create a fresh dedicated VM/LXC and run the standard Zulip installer there. Then the host-level ChatArch nginx proxies to that dedicated environment.

This is more correct than running Zulip standard installer directly on the current multi-service host.

I do not recommend

Running the standard Zulip installer directly on the current rexpc host where Discourse/Gitea/Stoat/OpenWebUI/etc. already exist. Zulip docs themselves advise against installing on an existing server with other nginx apps.

Product Placement

For the Agent community:

Discourse
  -> formal long-form topic, decisions, task memory, public knowledge base

Zulip
  -> structured realtime workroom, stream/topic/message, good for Agent operation rooms

Discord/Revolt/Stoat
  -> social realtime chat, channel/server/bot feel, less strict than Zulip

Agent Router
  -> bridges mentions/events from all surfaces to Hermes/Codex/CC Connect/etc.

Zulip is probably the most structured realtime option.


Project record:

/home/zhihong/Playground/projects/agent-community/07-28-zulip-self-host-deploy/

Full local report file:

/home/zhihong/Playground/projects/agent-community/07-28-zulip-self-host-deploy/reports/zulip-deployment-options.md

中文版说明

用户反馈英文阅读成本高;这一楼是 Zulip 部署方案评估的中文版本。

Zulip 自托管部署方案评估

结论先说

Zulip 和 Discord 不一样:Zulip 可以自托管。它也有官方托管版 Zulip Cloud,但这不影响我们自己部署 Zulip Server。

不过,Zulip 的部署方式需要慎重选择:

  • Zulip 官方默认推荐的生产部署方式是 标准 installer,不是 Docker。
  • 但标准 installer 会比较深地接管系统:安装/配置 nginx、PostgreSQL、Redis、RabbitMQ、memcached、Supervisor 等。
  • 当前 rexpc 已经跑了 Discourse、Gitea、Stoat/Revolt、Open WebUI 等多个服务,并且主机 Nginx 已经承担 ChatArch local/public 入口。
  • 所以我不建议直接在当前多服务主机上跑 Zulip 标准 installer
  • 如果目标是“尽量所有数据、配置、secrets 都放在 ChatArch 内部目录”,那么 Docker Compose 反而更容易约束路径。
  • 如果目标是“尽量不用 Docker”,更合适的是开一个独立 VM/LXC/容器化系统环境,在那里跑 Zulip 标准 installer,再由主机 Nginx 反代过去。

推荐排序:

  1. 当前机器快速 demo:用官方 Docker Compose,但所有数据 bind mount 到 /home/zhihong/.chatarch/zulip/,只监听 localhost 高端口。
  2. 长期非 Docker 生产部署:新开独立 VM/LXC,跑 Zulip 官方标准 installer。
  3. 不推荐:直接在当前 rexpc 主机上跑标准 installer,让它改现有系统 nginx/PostgreSQL/Redis/RabbitMQ。

Zulip 是不是更“规则化”?

是的。Zulip 比 Discord/Revolt 这种聊天工具更 structured。

Zulip 的核心模型是:

Organization
  -> Stream
      -> Topic
          -> Message

也就是说,每条消息都必须归到一个 topic 下面。它不像 Discord 那样容易变成频道里的长流水。

这对 Agent 社区很重要,因为 Agent 协作需要上下文边界:

  • 这个任务属于哪个 stream?
  • 这个讨论属于哪个 topic?
  • 哪些消息是同一个问题?
  • 哪个 Agent 应该响应?
  • 最后的结论应该沉淀到哪里?

Zulip 的 topic-first chat 模型比普通即时聊天更适合工程协作和 Agent 工作间。

Zulip 和 Discourse / Discord / Revolt 的区别

平台 核心形态 自托管 适合什么
Discourse 论坛 / topic / post / category 可以 长期讨论、公开知识库、决策沉淀
Zulip Stream / Topic / Message 的实时聊天 可以 工程团队、研究组、Agent 工作间
Discord Server / Channel / Thread / Voice 的 SaaS 聊天 官方不能 外部实时社区、bot 入口、语音/群聊
Revolt / Stoat Discord-like 自托管替代 可以 观察 Discord-like 体验、实时聊天 demo

更准确地说:

Discourse = 正式议题和长期沉淀
Zulip = 结构化实时工作间
Discord/Revolt/Stoat = 更社交化/频道化的实时聊天
Agent Router = 把这些入口统一接到 Agent runtime

Zulip 后端是什么?

Zulip 不是一个轻量单进程服务。它的后端主要包括:

  • Python / Django:主 Web 应用。
  • Tornado:实时消息推送 / long-polling。
  • PostgreSQL:持久化数据库。
  • Redis:短期状态、rate limit 等。
  • RabbitMQ:后台任务队列。
  • memcached:缓存。
  • nginx:静态资源和请求路由。
  • Supervisor:管理多个进程。

所以 Zulip 虽然可以不用 Docker,但“不用 Docker”不等于“轻量”。它仍然是一整套系统级服务。

Zulip 用 SQLite 吗?

不用。Zulip 使用 PostgreSQL。

这是合理的:

  • SQLite 更适合单机小工具、轻量应用、低并发场景。
  • Zulip 是多人实时聊天系统,需要并发写入、索引、事务、连接池和长期数据维护。
  • PostgreSQL 在这类场景里比 SQLite 合适得多。

Zulip 的生产数据主要在 PostgreSQL,此外还有 Redis、RabbitMQ、memcached 等组件辅助实时和队列功能。

方案 A:Zulip 标准 installer

定位

这是 Zulip 官方默认的生产安装方式,不使用 Docker。

典型命令类似:

curl -fLO https://download.zulip.com/server/zulip-server-latest.tar.gz
tar -xf zulip-server-latest.tar.gz
./zulip-server-*/scripts/setup/install --email=YOUR_EMAIL --hostname=YOUR_HOSTNAME

installer 会设置:

EXTERNAL_HOST
ZULIP_ADMINISTRATOR

数据和配置位置

标准安装会落到系统级路径:

/etc/zulip/settings.py
/etc/zulip/zulip.conf
/home/zulip/deployments/current/
/home/zulip/prod-static/
/var/log/zulip/
系统 PostgreSQL 数据目录
系统 nginx 配置

优点

  • 官方默认生产路线。
  • 不用 Docker。
  • 官方文档明确说,相比 Docker,标准 installer 在安装、维护、升级上通常更省心。
  • 如果是 fresh VM / dedicated machine,这是最正统的路线。

问题

当前 rexpc 不是 fresh machine,而是已经跑了很多 ChatArch 服务。

Zulip 官方文档也强调:标准 installer 期望 Zulip 是系统里的主要服务,会安装和配置 nginx、PostgreSQL、Redis 等系统包。如果你在已有 nginx app 的机器上安装,官方不推荐。

对我们当前机器来说,风险包括:

  • 改动 /etc/nginx,影响已有 local/public 入口。
  • 安装/改动系统 PostgreSQL。
  • 安装/改动 Redis、RabbitMQ、memcached。
  • 产生 /home/zulip/etc/zulip/var/log/zulip 等系统级目录。
  • 不容易完整收纳到 /home/zhihong/.chatarch/zulip/
  • 后续卸载也不方便。

所以:不建议直接在当前多服务主机上跑标准 installer。

方案 B:官方 Docker / Docker Compose

定位

Zulip 官方也提供 Docker image:

ghcr.io/zulip/zulip-server:12.1-0

Zulip Docker 文档说:如果组织偏好容器化部署,可以用 Docker;但相比标准 installer,Docker 会适度增加安装、维护、升级成本。

Compose 栈

官方 Docker Compose 包含:

zulip-server
PostgreSQL
memcached
RabbitMQ
Redis

默认 compose 里 Zulip 服务会暴露:

25/tcp   SMTP
80/tcp   HTTP
443/tcp  HTTPS

所以如果在当前机器部署,必须先检查和覆盖端口,不能让它抢主机的 80/443

ChatArch 内部数据布局

Docker Compose 的优势是可以把数据 bind mount 到 ChatArch 内部:

/home/zhihong/.chatarch/zulip/
  compose/
  data/
    zulip/
    postgresql-14/
    rabbitmq/
    redis/
  secrets/
  logs/
  backups/

然后只监听:

127.0.0.1:3095 -> Zulip container HTTP

主机 Nginx 再做:

zulip.local.wzhecnu.cn -> 127.0.0.1:3095
zulip.public.wzhecnu.cn -> public 自动入口 -> local nginx -> 127.0.0.1:3095

优点

  • 更容易保持数据、配置、secrets 都在 /home/zhihong/.chatarch/zulip/
  • 不会让 Zulip 标准 installer 改主机 /etc/nginx
  • 不会污染主机 PostgreSQL / Redis / RabbitMQ。
  • 更适合当前已有很多服务的 rexpc
  • demo 阶段如果不满意,清理也更可控。

缺点

  • 用户偏好不太喜欢 Docker。
  • 官方说 Docker 维护/升级比标准 installer 略麻烦。
  • 仍然是多服务栈,不是轻量应用。
  • 必须仔细检查 effective compose config,避免误暴露 25/80/443

方案 C:新开 VM/LXC,跑标准 installer

这是我认为最干净的非 Docker 方案。

结构类似:

主机 Nginx / public-entry
    -> 转发到 Zulip VM/LXC

Zulip VM/LXC
    -> 标准 installer
    -> 自己的 nginx/PostgreSQL/Redis/RabbitMQ/memcached

优点

  • 不用 Docker。
  • 符合 Zulip 官方默认生产路线。
  • Zulip 可以在独立系统里接管 nginx/PostgreSQL/Redis 等,不影响当前 rexpc
  • 比直接污染当前主机更安全。

缺点

  • 需要先准备 VM/LXC/systemd-nspawn/LXD 之类的隔离环境。
  • 数据默认在那个隔离环境里,不天然都在 /home/zhihong/.chatarch/zulip/,除非我们专门挂载目录。
  • 比 Docker demo 更慢一些。

方案 D:源码/开发环境安装

Zulip 源码开发环境适合开发 Zulip 本身,不适合作为长期生产服务。

不建议把它作为这次部署路线。

当前建议

如果目标是“先部署一个可看的 Zulip demo,而且不要影响当前服务器服务”,我建议:

官方 Docker Compose + ChatArch bind mount + localhost 高端口 + 主机 Nginx local/public 入口

如果目标是“长期生产,且坚持不用 Docker”,我建议:

新开独立 VM/LXC + Zulip 标准 installer + 主机 Nginx 反代

我不建议:

直接在当前 rexpc 上跑 Zulip 标准 installer

因为这和 Zulip 官方建议相冲突,也和我们当前 ChatArch 多服务主机的稳定性要求冲突。

对 Agent 社区的定位

Zulip 很适合作为 Agent 社区里的“结构化实时工作间”:

Discourse
  正式 topic、任务背景、结论、公开知识库

Zulip
  实时 stream/topic/message 工作间,适合工程协作和 Agent 运行讨论

Discord/Revolt/Stoat
  更社交化、频道化、bot/voice 的实时聊天体验

Agent Router
  把这些入口的 mention、topic、tag、webhook 统一路由到 Hermes/Codex/CC Connect 等 runtime

Zulip 可能是目前几个实时聊天选项里最适合“Agent 工作流”的,因为它强制 topic,有天然上下文边界。


本地中文报告文件:

/home/zhihong/Playground/projects/agent-community/07-28-zulip-self-host-deploy/reports/zulip-deployment-options.zh.md