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.orayhost, 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/nginxand 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/443accidentally. - 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:
- Prefer not Docker if possible.
- 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