Бэкап и восстановление Zulip
Zulip — редкий случай мессенджера, где тредовая модель обсуждений заменяет привычную линейную ленту: в одном канале живут десятки параллельных тем, и команда не тонет в потоке сообщений. Именно поэтому его выбирают для больших распределённых команд — а значит, потеря истории обсуждений при сбое сервера обходится дороже, чем в случае с обычным чатом. Разберём, как бэкапить Zulip правильно: что входит в бэкап, как его снять штатными средствами и вручную, как восстановиться на новом сервере и какие грабли ждут на этом пути.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что на самом деле нужно бэкапить в Zulip
Zulip — не однокомпонентное приложение. Стандартная установка (Zulip Server) поднимает на одной машине сразу несколько сервисов, и понимание их роли определяет, что класть в бэкап, а что нет:
- PostgreSQL — вся история сообщений, пользователи, стримы (каналы), права доступа, настройки организации. Это ядро бэкапа.
- Загруженные файлы — вложения, аватары, кастомные эмодзи. Хранятся либо локально в
/home/zulip/uploads, либо во внешнем S3-совместимом хранилище, если вы его настроили при установке. - Конфигурация и секреты —
/etc/zulip/settings.py,/etc/zulip/zulip-secrets.conf,/etc/zulip/zulip.conf. Без них база данных бесполезна: в secrets лежат ключи шифрования сессий, пароль от Postgres, токены интеграций. - RabbitMQ и Redis — очереди задач и кеш. Это транзитные данные: после падения сервиса они пересоздаются автоматически, бэкапить их не нужно.
- Memcached — то же самое, чистый кеш, восстановление не требуется.
Ключевой вывод: бэкап Zulip — это связка «дамп PostgreSQL + каталог uploads + конфиги из /etc/zulip», а не просто копия базы. Если вы бэкапите только pg_dump, при восстановлении вы получите рабочую организацию без единой аватарки и без вложений в сообщениях.
Официальный инструмент: manage.py backup
В комплекте Zulip есть встроенная команда для полного бэкапа, которая учитывает все перечисленные компоненты за один запуск. Выполняется от имени пользователя zulip:
su zulip -c '/home/zulip/deployments/current/manage.py backup'
Команда создаёт архив в /home/zulip/backups/ — по умолчанию это tar-файл с меткой времени в имени, внутри которого лежат дамп базы данных, каталог с загруженными файлами и снимок конфигурации. Посмотреть доступные опции (например, путь вывода или исключение части данных) стоит через встроенную справку, потому что флаги между релизами Zulip иногда меняются:
su zulip -c '/home/zulip/deployments/current/manage.py backup --help'
Полезная деталь: команда сама берёт консистентный снимок PostgreSQL (через pg_dump во внутреннем формате), поэтому не нужно останавливать сервис Zulip на время бэкапа — организация продолжает принимать сообщения.
Готовый архив стоит сразу забрать с сервера — если диск с самим Zulip умрёт, локальная копия бэкапа в /home/zulip/backups/ не поможет:
scp zulip-server:/home/zulip/backups/zulip-backup-*.tar.gz /local/backups/
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверВосстановление на новом сервере
Здесь у Zulip есть важное ограничение, которое ломает многим первый запуск восстановления: версия Zulip на новом сервере должна совпадать с версией, на которой снимался бэкап (как минимум — та же мажорная ветка). Восстановить бэкап от Zulip 9.x на свежеустановленный Zulip 10.x штатным способом не получится: схема базы и формат конфигов между релизами меняются.
Порядок действий:
- Разверните на новом сервере чистый Zulip той же версии — обычным установочным скриптом (
./zulip-server-*/scripts/setup/install), но без прогона мастера первичной настройки организации. - Скопируйте архив бэкапа на сервер.
- Запустите восстановление от root:
sudo /home/zulip/deployments/current/scripts/setup/restore-backup /path/to/zulip-backup-*.tar.gz
Скрипт сам поднимает базу данных из дампа, раскладывает файлы по местам, применяет конфигурацию и перезапускает сервисы через supervisor. По завершении стоит проверить статус всех процессов:
sudo supervisorctl status
Если какой-то из процессов (zulip-django, zulip-tornado, zulip-workers:*) не в состоянии RUNNING — смотрите лог в /var/log/zulip/, чаще всего дело в правах на каталог uploads после переноса или в устаревшем секрете, не совпавшем с новым /etc/zulip/zulip-secrets.conf.
Если вы переносите Zulip на сервер с другой ОС или архитектурой процессора, дополнительно проверьте, что версии PostgreSQL совместимы — расхождение мажорной версии Postgres иногда требует ручного pg_upgrade до штатного восстановления. Общие принципы такого переноса разобраны в статье про восстановление базы данных из бэкапа на практике.
Ручной бэкап: pg_dump и rsync
Штатная команда удобна, но не всегда вписывается в существующую инфраструктуру бэкапов — например, если вы уже льёте всё через borgbackup или restic в единое хранилище. В этом случае логичнее собирать бэкап Zulip вручную из тех же трёх частей.
Дамп базы данных (от пользователя postgres, база по умолчанию называется zulip):
sudo -u postgres pg_dump -Fc zulip > /backup/zulip-db-$(date +%F).dump
Формат -Fc (custom) сжимает дамп и позволяет восстанавливать выборочно — это удобнее, чем текстовый SQL-дамп, если база большая.
Загруженные файлы и конфигурация:
rsync -a /home/zulip/uploads/ /backup/zulip-uploads/
rsync -a /etc/zulip/ /backup/zulip-etc/
Восстановление в этом сценарии тоже ручное: разворачиваете базу через pg_restore, кладёте файлы обратно в /home/zulip/uploads с правами пользователя zulip, конфиги — в /etc/zulip, и перезапускаете сервисы:
sudo -u postgres pg_restore -d zulip --clean --if-exists /backup/zulip-db-2026-08-30.dump
sudo chown -R zulip:zulip /home/zulip/uploads
sudo supervisorctl restart all
Минус этого пути — вы теряете гарантию консистентности, которую даёт встроенный скрипт: если pg_dump и rsync каталога uploads выполняются не одновременно, теоретически можно получить дамп базы, в котором есть ссылка на вложение, а самого файла в снятой копии uploads ещё нет (или наоборот). На практике для большинства команд это не критично — расхождение на несколько секунд редко ловит именно тот файл, который кто-то только что прикрепил, но если для вас это важно, надёжнее оставаться на manage.py backup.
Автоматизация и хранение бэкапов вне сервера
Ручной бэкап раз в квартал не спасёт при внезапном сбое диска. Базовая схема — ежедневный бэкап по cron с выгрузкой на отдельное хранилище:
# /etc/cron.d/zulip-backup
0 3 * * * root su zulip -c '/home/zulip/deployments/current/manage.py backup' >> /var/log/zulip-backup.log 2>&1
30 3 * * * root find /home/zulip/backups/ -mtime +7 -delete
Второй строкой чистим локальные копии старше недели — иначе архивы (особенно с большими вложениями) съедят весь диск. Само хранилище бэкапов имеет смысл держать на другом сервере или в отдельном объектном хранилище — например, через rclone синхронизировать /home/zulip/backups/ в S3-совместимый бакет сразу после снятия копии. Похожая логика ротации и выгрузки за пределы сервера подробно разобрана в статье про бэкап и восстановление Mattermost — принципы «3-2-1» для командных чатов одинаковы независимо от конкретного продукта.
Если Zulip растёт и загруженные файлы занимают заметную часть диска, стоит заранее прикинуть, каким должен быть сервер под саму рабочую нагрузку и под хранение бэкапов отдельно — эти требования лучше не смешивать на одном томе.
| Что бэкапим | Инструмент | Частота | Куда складывать |
|---|---|---|---|
| БД + uploads + конфиги | manage.py backup | Ежедневно | Отдельный сервер/S3 |
| Только БД (доп. защита) | pg_dump -Fc | Каждые 6 часов | Локально + offsite |
| Полный образ диска | снапшот провайдера | Перед апгрейдом | Хранилище провайдера |
Типичные проблемы при бэкапе и восстановлении
- «No space left on device» во время backup. Каталог
/home/zulip/backups/живёт на том же диске, что и рабочая установка. Если места мало, команда падает на этапе сборки архива. Указывайте отдельный путь вывода на другом томе или чистите старые архивы перед каждым запуском. - Восстановление падает на разнице версий Zulip. Самая частая причина неудачного
restore-backup— попытка накатить старый бэкап на только что установленную последнюю версию. Сначала поднимите ту же версию, что была на исходном сервере, восстановитесь, а затем уже обновляйте штатной процедурой апгрейда. - После restore не открываются старые вложения. Обычно значит, что
rsync/копированиеuploadsпрервалось или права на каталог достались не пользователюzulip. Проверьтеchown -R zulip:zulip /home/zulip/uploadsи сверьте размер каталога с исходным сервером. - secrets.conf не совпадает — ошибки авторизации после восстановления.
zulip-secrets.confсодержит ключ подписи сессий; если вы восстановили базу, но взяли secrets с нового чистого сервера, все существующие сессии и токены API станут невалидны. Секреты нужно восстанавливать вместе с базой, из того же бэкапа. - Бэкап снимается, но никто не проверял восстановление. Классическая ошибка любой системы бэкапов — узнать, что архив битый или неполный, только в момент аварии. Раз в один-два месяца стоит поднимать восстановление на тестовом сервере и убеждаться, что организация реально открывается.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли бэкапить Zulip без остановки сервиса?
Да, manage.py backup снимает консистентный снимок базы через pg_dump без блокировки записи — пользователи могут продолжать работать во время бэкапа.
Сколько весит типичный бэкап Zulip?
Зависит от объёма истории сообщений и вложений: сама база данных обычно занимает от десятков до сотен мегабайт на среднюю команду, а основной вес добавляют загруженные файлы и эмодзи — точный размер стоит смотреть по своему архиву, универсальных цифр тут нет.
Что делать, если бэкап снимался на другой версии Zulip?
Сначала разверните ту версию Zulip, на которой был сделан бэкап, восстановитесь на ней штатным restore-backup, а уже потом выполните обновление до нужной версии официальной процедурой апгрейда — так избежите рассинхрона схемы базы.
Нужно ли бэкапить RabbitMQ и Redis?
Нет, это транзитные очереди и кеш — после восстановления Zulip из бэкапа базы, файлов и конфигов они пересоздаются автоматически при первом запуске сервисов.
Подходит ли обычный снапшот диска вместо manage.py backup?
Снапшот тома у облачного провайдера — рабочий вариант для быстрого отката перед рискованной операцией (например, апгрейдом), но он привязан к конкретному серверу и провайдеру. Для регулярного offsite-бэкапа надёжнее штатный manage.py backup, который можно выгружать куда угодно.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →