Installing SSL Certificates

To keep your communications secure, Zulip runs over HTTPS only. You’ll need an SSL/TLS certificate.

Fortunately, since about 2017, new options can make getting and maintaining a genuine, trusted-by-browsers certificate no longer the chore (nor expense) that it used to be.

Manual install

If you already have an SSL certificate, just install (or symlink) its files into place at the following paths:

  • /etc/ssl/private/zulip.key for the private key
  • /etc/ssl/certs/zulip.combined-chain.crt for the certificate.

Your certificate file should contain not only your own certificate but its full chain, including any intermediate certificates used by your CA. See the nginx documentation for details on what this means. If you’re missing part of the chain, your server may work with some browsers, but not others and not the Zulip Android app.


Just trying in a browser is not an adequate test, because some browsers ignore errors that others don’t.

Two good tests include:

  • If your server is accessible from the public Internet, use the SSL Labs tester. Be sure to check for “Chain issues”; if any, your certificate file is missing intermediate certificates.
  • Alternatively, run a command like curl -SsI (using your server’s URL) from a machine that can reach your server. Make sure that on the same machine, curl -SsI gives an error; curl on some machines, including Macs, will accept incomplete chains.

Self-signed certificate

If you aren’t able to use Certbot, you can generate a self-signed SSL certificate. This isn’t suitable for production use (because it’s insecure, and because browsers and the Zulip apps will complain that it’s insecure), but may be convenient for testing.

To generate a self-signed certificate when first installing Zulip, just pass the --self-signed-cert flag when running the install script.

To generate a self-signed certificate for an already-installed Zulip server, run the following commands:

sudo -s  # If not already root
/home/zulip/deployments/current/scripts/setup/generate-self-signed-cert HOSTNAME

where HOSTNAME is the domain name (or IP address) to use on the generated certificate.

After replacing the certificates, you need to reload nginx by running the following as root:

service nginx reload