8.2.18 Deployment of the corporate chat server Zulip
Zulip is a modern open-source team communication system that combines real-time messaging with asynchronous threaded conversations. Deploying it with Docker enables fast and reproducible installation, eliminating the need to configure dependencies manually (PostgreSQL, RabbitMQ, Redis, memcached, etc.).
Server Preparation
Requirements
- A Virtual or Dedicated server;
- Minimum system requirements: 2 vCPU, 4 GB RAM, 20 GB SSD;
- Root access or a user with
sudo
privileges; - Docker and Docker Compose must be installed.
Variables to Replace
DOMAIN_NAME
— your domain name (e.g.,chat.example.com
);ADMIN_EMAIL
— Zulip administrator’s email address;POSTGRES_PASSWORD
,RABBITMQ_PASSWORD
,REDIS_PASSWORD
,MEMCACHED_PASSWORD
— service passwords;SECRET_KEY
— a 50-character random string (DjangoSECRET_KEY
);
Security Configuration
Restrict access to non-public ports and allow only the required services.
UFW:
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable
iptables:
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -P INPUT DROP
Installation
First, create a directory for the project:
mkdir ~/zulip && cd ~/zulip
Then clone the docker-zulip
repository:
git clone https://github.com/zulip/docker-zulip.git
cd docker-zulip
The repository includes a sample docker-compose.yml
file that defines five containers: Zulip, PostgreSQL, Redis, RabbitMQ, and memcached.
Tip: to generate secure random keys, use:
openssl rand -base64 40 | tr -d '/+=' | head -c 50
Now edit docker-compose.yml
. Locate the environment
section under the zulip
service and insert your values:
services:
zulip:
image: zulip/docker-zulip:10.4-0 # latest tag
environment:
- SETTING_EXTERNAL_HOST=DOMAIN_NAME
- SETTING_ZULIP_ADMINISTRATOR=ADMIN_EMAIL
- POSTGRES_PASSWORD=POSTGRES_PASSWORD
- SECRETS_postgres_password=POSTGRES_PASSWORD
- RABBITMQ_DEFAULT_PASS=RABBITMQ_PASSWORD
- SECRETS_rabbitmq_password=RABBITMQ_PASSWORD
- REDIS_PASSWORD=REDIS_PASSWORD
- SECRETS_redis_password=REDIS_PASSWORD
- SECRETS_secret_key=SECRET_KEY
- SSL_CERTIFICATE_GENERATION=certbot
Warning: after the first launch, service passwords can only be changed manually inside containers or by recreating data volumes.
Pull Images and Launch Zulip
Run the following commands to pull the latest images and start all five containers in the background:
sudo docker compose pull
sudo docker compose up -d
Creating an Organization
Generate an organization creation link with the following command:
sudo docker compose exec -u zulip zulip \
"/home/zulip/deployments/current/manage.py generate_realm_creation_link"
Open the generated link in your browser and create an admin account:
Verifying Functionality
- Check that all containers are marked as “healthy”:
docker compose ps
- Open
https://<DOMAIN_NAME>/
and log in with the admin account you created.
3. In the admin menu, go to Administration → Server logs and verify there are no errors.
Common Issues
Error | Cause | Solution |
---|---|---|
port 5432 is already allocated |
Local PostgreSQL service is running | Stop the postgresql service or change the port in docker-compose.yml . |
502 Bad Gateway / self‑signed cert | Let’s Encrypt certificate has not yet been issued | Wait for Certbot to finish or temporarily use HTTP. |
django.core.exceptions.ImproperlyConfigured: SECRET_KEY |
The SECRETS_secret_key variable is missing |
Generate a new key, add it to docker-compose.yml , and restart the container. |
Not enough RAM, “worker not running” queue warning | Server lacks memory for multiprocess workers | Set QUEUE_WORKERS_MULTIPROCESS=false or upgrade RAM. |
Official Resources