Zulip is a self-hosted open-source team messaging platform with a unique threaded topic model that keeps conversations organized at scale. Unlike simpler chat tools, Zulip has real infrastructure depth: it stores messages in PostgreSQL, uses Redis for caching, routes async tasks through RabbitMQ, and depends on working email delivery for notifications and account management. When any of these layers fails, different parts of Zulip break in different ways — and some failures are invisible until a user reports them. Vigilmon gives you uptime monitoring, API health checks, and heartbeat-based email delivery verification across the entire stack.
What You'll Set Up
- HTTP uptime monitor for the Zulip web server
- API health check via
/api/v1/server_settings - Database and service connectivity alerts
- Email delivery verification via Vigilmon heartbeat
- SSL certificate expiry alert
Prerequisites
- Zulip server running (default HTTPS on port
443) - Admin access to your Zulip instance
- A free Vigilmon account
Step 1: Monitor the Zulip Web Server
Confirm that Zulip's nginx frontend is up and serving requests:
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter your Zulip URL:
https://chat.yourdomain.com. - Set Check interval to
5 minutes. - Set Expected HTTP status to
200. - Click Save.
Zulip always runs behind nginx (bundled in the official install). A 200 on the root path confirms nginx is up and the Django application server (gunicorn) is responding behind it. If gunicorn crashes, nginx returns 502 Bad Gateway — Vigilmon catches this immediately.
Step 2: Health Check via the Server Settings API
Zulip exposes a public server settings endpoint that requires no authentication and returns configuration details when the application is healthy:
- Add a second HTTP / HTTPS monitor.
- URL:
https://chat.yourdomain.com/api/v1/server_settings - Set Expected HTTP status to
200. - Enable Keyword check and enter
realm_urias the expected keyword. - Set Check interval to
5 minutes. - Click Save.
A healthy response looks like:
{
"realm_uri": "https://chat.yourdomain.com",
"realm_name": "Your Organization",
"zulip_version": "8.3",
"authentication_methods": {...},
...
}
This endpoint is lighter than a full login check and doesn't require credentials — making it ideal for external monitoring. If Zulip's Django application is unresponsive or misconfigured, this endpoint returns an error or times out, triggering a Vigilmon alert.
Step 3: Monitor Database and Service Connectivity
Zulip's backend depends on three services: PostgreSQL (message storage), Redis (caching and presence), and RabbitMQ (async task queue). When any of these goes down, Zulip degrades in specific ways — messages fail to send, presence goes stale, or email notifications stop queuing.
Use Vigilmon's keyword check on a diagnostic endpoint to detect backend degradation:
- Add a third HTTP / HTTPS monitor.
- URL:
https://chat.yourdomain.com/health - Set Expected HTTP status to
200. - Enable Keyword check and enter
{"status":"healthy"}as the expected keyword. - Set Check interval to
5 minutes. - Click Save.
Zulip's /health endpoint (available since Zulip 7.0) checks internal connectivity to PostgreSQL, Redis, and RabbitMQ and returns a combined health status. If any backend service is unreachable, the response changes and the keyword check fails — alerting you to investigate:
# Check service status on the Zulip server
/home/zulip/deployments/current/scripts/run-zulip-server-as-zulip check-rabbitmq-queue
sudo -u zulip /home/zulip/deployments/current/manage.py dbshell
redis-cli ping
Step 4: Email Delivery Verification via Heartbeat
Zulip's email delivery is critical for account management (password resets, invitations) and notification emails. SMTP failures often go unnoticed until a user can't reset their password. Use Vigilmon's cron heartbeat to verify emails are flowing:
- In Vigilmon, click Add Monitor → Cron Heartbeat.
- Set the expected ping interval to
60 minutes. - Copy the heartbeat URL (e.g.
https://vigilmon.online/heartbeat/abc123).
Now create a Zulip bot that pings Vigilmon after sending a test email. On your Zulip server:
# /home/zulip/email_heartbeat.py
import subprocess
import urllib.request
# Send a test email via Zulip's mail utility
result = subprocess.run(
['/home/zulip/deployments/current/manage.py', 'send_test_email', 'healthcheck@example.com'],
capture_output=True, text=True
)
if result.returncode == 0:
# Only ping Vigilmon if email send succeeded
urllib.request.urlopen('https://vigilmon.online/heartbeat/abc123', timeout=5)
Schedule it with cron:
# crontab -e (as zulip user)
0 * * * * /usr/bin/python3 /home/zulip/email_heartbeat.py >> /var/log/zulip/email_heartbeat.log 2>&1
If the heartbeat stops arriving, Vigilmon alerts you — indicating either the cron job stopped running or SMTP delivery is broken.
Step 5: SSL Certificate Alert
Zulip's official installer configures Let's Encrypt by default. Auto-renewal can fail if port 80 is blocked or the renewal script has a permission issue. Monitor the certificate:
- Open the web server monitor from Step 1.
- Enable Monitor SSL certificate.
- Set Alert when certificate expires in less than
21 days. - Click Save.
An expired certificate on a Zulip instance causes all connected clients (desktop, mobile, web) to show TLS errors and refuse to connect — a complete outage. The 21-day window gives you time to investigate and manually renew:
# Check Zulip's Let's Encrypt renewal status
/home/zulip/deployments/current/scripts/setup/renew-cert
Monitoring Summary
| Monitor | What it detects |
|---|---|
| Web server (/) | nginx down, gunicorn crash (502) |
| /api/v1/server_settings | Django app unresponsive, config error |
| /health | PostgreSQL, Redis, or RabbitMQ failure |
| Cron heartbeat | SMTP delivery broken, cron job stopped |
| SSL certificate | Expiring TLS cert before client errors |
Configure Vigilmon notifications (Settings → Notifications) to alert your team via Slack, Discord, email, or webhook. With all five monitors active, you'll catch Zulip outages at the infrastructure layer — before your team notices the chat is down.