Secure, maintain, and upgrade

This page covers topics that will help you maintain a healthy, up-to-date, and secure Zulip installation, including:

You may also want to read this related content:

Upgrading

We recommend reading this entire section before doing your first upgrade.

To upgrade to a new version of the zulip server, download the appropriate release tarball from https://www.zulip.org/dist/releases/

You also have the option of creating your own release tarballs from a copy of the zulip.git repository using tools/build-release-tarball. And, starting with Zulip version 1.4, you can upgrade Zulip to a version in a Git repository directly.

Next, run as root:

/home/zulip/deployments/current/scripts/upgrade-zulip zulip-server-VERSION.tar.gz

The upgrade process will shut down the Zulip service and then run apt-get upgrade, a puppet apply, any database migrations, and then bring the Zulip service back up. Upgrading will result in some brief downtime for the service, which should be under 30 seconds unless there is an expensive transition involved. Unless you have tested the upgrade in advance, we recommend doing upgrades at off hours.

Note that upgrading an existing Zulip production server from Ubuntu 14.04 Trusty to Ubuntu 16.04 Xenial will require significant manual intervention on your part to migrate the data in the database from Postgres 9.3 to Postgres 9.5. Contributions on testing and documenting this process are welcome!

Preserving local changes to configuration files

Warning: If you have modified configuration files installed by Zulip (e.g. the nginx configuration), the Zulip upgrade process will overwrite your configuration when it does the puppet apply.

You can test whether this will happen assuming no upstream changes to the configuration using scripts/zulip-puppet-apply (without the -f option), which will do a test puppet run and output and changes it would make. Using this list, you can save a copy of any files that you've modified, do the upgrade, and then restore your configuration.

If you need to do this, please report the issue so that we can make the Zulip puppet configuration flexible enough to handle your setup.

Troubleshooting with the upgrade log

The Zulip upgrade script automatically logs output to /var/log/zulip/upgrade.log. Please use those logs to include output that shows all errors in any bug reports.

After the upgrade, we recommend checking /var/log/zulip/errors.log to confirm that your users are not experiencing errors after the upgrade.

Rolling back to a prior version

The Zulip upgrade process works by creating a new deployment under /home/zulip/deployments/ containing a complete copy of the Zulip server code, and then moving the symlinks at /home/zulip/deployments/current and /root/zulip as part of the upgrade process.

This means that if the new version isn't working, you can quickly downgrade to the old version by using /home/zulip/deployments/<date>/scripts/restart-server to return to a previous version that you've deployed (the version is specified via the path to the copy of restart-server you call).

Updating settings

If required, you can update your settings by editing /etc/zulip/settings.py and then run /home/zulip/deployments/current/scripts/restart-server to restart the server.

Applying Ubuntu system updates

While the Zulip upgrade script runs apt-get upgrade, you are responsible for running this on your system on a regular basis between Zulip upgrades to ensure that it is up to date with the latest security patches.

API and your Zulip URL

To use the Zulip API with your Zulip server, you will need to use the API endpoint of e.g. https://zulip.example.com/api. Our Python API example scripts support this via the --site=https://zulip.example.com argument. The API bindings support it via putting site=https://zulip.example.com in your .zuliprc.

Every Zulip integration supports this sort of argument (or e.g. a ZULIP_SITE variable in a zuliprc file or the environment), but this is not yet documented for some of the integrations (the included integration documentation on /integrations will properly document how to do this for most integrations). We welcome pull requests for integrations that don't discuss this!

Similarly, you will need to instruct your users to specify the URL for your Zulip server when using the Zulip desktop and mobile apps.

Memory leak mitigation

As a measure to mitigate the impact of potential memory leaks in one of the Zulip daemons, the service automatically restarts itself every Sunday early morning. See /etc/cron.d/restart-zulip for the precise configuration.

Upgrading from a git repository

Starting with version 1.4, the Zulip server supports doing deployments from a Git repository. To configure this, you will need to add zulip::static_asset_compiler to your /etc/zulip/zulip.conf file's puppet_classes entry, like this:

puppet_classes = zulip::voyager, zulip::static_asset_compiler

Then, run scripts/zulip-puppet-apply to install the dependencies for building Zulip's static assets. You can configure the git repository that you'd like to use by adding a section like this to /etc/zulip/zulip.conf; by default it uses the main zulip repository (shown below).

[deployment]
git_repo_url = https://github.com/zulip/zulip.git

Once that is done (and assuming the currently installed version of Zulip is new enough that this script exists), you can do deployments by running as root:

/home/zulip/deployments/current/scripts/upgrade-zulip-from-git <branch>

and Zulip will automatically fetch the relevant branch from the specified repository, build the static assets, and deploy that version. Currently, the upgrade process is slow, but it doesn't need to be; there is ongoing work on optimizing it.

Backups

There are several pieces of data that you might want to back up:

If you are interested in backups because you are moving from one Zulip server to another server and can't transfer a full postgres dump (which is definitely the simplest approach), our draft conversion and export design document may help. The tool is well designed and was tested carefully with dozens of realms as of mid-2016 but is not integrated into Zulip's regular testing process, and thus it is worth asking on the Zulip developers mailing list whether it needs any minor updates to do things like export newly added tables.

Restore from backups

To restore from backups, the process is basically the reverse of the above:

This restoration process can also be used to migrate a Zulip installation from one server to another.

We recommend running a disaster recovery after you setup backups to confirm that your backups are working; you may also want to monitor that they are up to date using the Nagios plugin at: puppet/zulip_internal/files/nagios_plugins/check_postgres_backup.

Contributions to more fully automate this process or make this section of the guide much more explicit and detailed are very welcome!

Postgres streaming replication

Zulip has database configuration for using Postgres streaming replication; you can see the configuration in these files:

Contribution of a step-by-step guide for setting this up (and moving this configuration to be available in the main puppet/zulip/ tree) would be very welcome!

Monitoring

The complete Nagios configuration (sans secret keys) used to monitor zulip.com is available under puppet/zulip_internal in the Zulip Git repository (those files are not installed in the release tarballs).

The Nagios plugins used by that configuration are installed automatically by the Zulip installation process in subdirectories under /usr/lib/nagios/plugins/. The following is a summary of the various Nagios plugins included with Zulip and what they check:

Application server and queue worker monitoring:

Database monitoring:

Standard server monitoring:

If you're using these plugins, bug reports and pull requests to make it easier to monitor Zulip and maintain it in production are encouraged!

Scalability

This section attempts to address the considerations involved with running Zulip with a large team (>1000 users).

Questions, concerns, and bug reports about this area of Zulip are very welcome! This is an area we are hoping to improve.

Securing your Zulip server

Zulip's security model is discussed in a separate document.

Management commands

Zulip has a large library of Django management commands. To use them, you will want to be logged in as the zulip user and for the purposes of this documentation, we assume the current working directory is /home/zulip/deployments/current.

Below, we should several useful examples, but there are more than 100 in total. We recommend skimming the usage docs (or if there are none, the code) of a management command before using it, since they are generally less polished and more designed for expert use than the rest of the Zulip system.

manage.py shell

You can get an iPython shell with full access to code within the Zulip project using manage.py shell, e.g., you can do the following to change an email address:

$ /home/zulip/deployments/current/manage.py shell
In [1]: user_profile = get_user_profile_by_email("email@example.com")
In [2]: do_change_user_email(user_profile, "new_email@example.com")

manage.py dbshell

This will start a postgres shell connected to the Zulip database.

Grant administrator access

You can make any user a realm administrator on the command line with the knight management command:

./manage.py knight username@example.com -f

Creating API super users with manage.py

If you need to manage the IRC, Jabber, or Zephyr mirrors, you will need to create API super users. To do this, use ./manage.py knight with the --permission=api_super_user argument. See bots/irc-mirror.py and bots/jabber_mirror.py for further detail on these.

Exporting users and realms with manage.py export

If you need to do an export of a single user or of an entire realm, we have tools in management/ that essentially export Zulip data to the file system.

export_single_user.py exports the message history and realm-public metadata for a single Zulip user (including that user's received messages as well as their sent messages).

A good overview of the process for exporting a single realm when moving a realm to a new server (without moving a full database dump) is in management/export.py. We recommend you read the comment there for words of wisdom on speed, what is and is not exported, what will break upon a move to a new server, and suggested procedure.

Other useful manage.py commands

There are a large number of useful management commands under zerver/management/commands/; you can also see them listed using ./manage.py with no arguments.