Zulip на сервере: частые ошибки и решения
Zulip — редкий мессенджер, где обсуждения идут тредами внутри тем, а не сплошной лентой, поэтому крупные команды в нём не тонут в потоке сообщений. Но установочный скрипт Zulip требователен к окружению: нехватка памяти, кривой DNS, чужая версия PostgreSQL или неправильная локаль обрушивают деплой на середине. Ниже — конкретные ошибки, с которыми чаще всего сталкиваются при самостоятельной установке Zulip Server, и как их закрыть без переустановки с нуля.
Содержание
- Недостаточно памяти: скрипт зависает или падает без внятной ошибки
- Установочный скрипт zulip.sh падает на середине
- Ошибка при выпуске SSL-сертификата
- RabbitMQ не стартует или очереди не разгребаются
- PostgreSQL: медленный поиск и ошибки при миграциях
- Email-уведомления не приходят
- Обновление Zulip и откат при неудачном апгрейде
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Недостаточно памяти: скрипт зависает или падает без внятной ошибки
Zulip Server — это не один процесс, а связка: Django-приложение, Tornado для realtime, PostgreSQL, RabbitMQ, Redis, Memcached и Nginx, каждый со своим воркер-пулом. На установке с 1 ГБ RAM zulip.sh либо зависает на шаге сборки статики, либо процесс убивает OOM killer — в логе dmesg при этом видно Out of memory: Killed process.
Официальный минимум для тестовой установки — 2 ГБ, для рабочей организации на 20-30 человек комфортнее 4 ГБ.
| Размер команды | RAM | vCPU | Диск |
|---|---|---|---|
| Тест/пилот, до 10 человек | 2 ГБ | 1-2 | 20 ГБ SSD |
| Рабочая команда, 20-50 человек | 4 ГБ | 2 | 40 ГБ SSD |
| 100+ человек, активная история сообщений | 8 ГБ | 4 | 80+ ГБ SSD |
Если апгрейдить сервер прямо сейчас не вариант, временно спасает swap — на установке он не заменяет RAM по скорости, но не даёт процессу упасть:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
После установки swap можно оставить как страховку на пиковую нагрузку, но для боевой эксплуатации это костыль — правильный путь — сервер с запасом по памяти.
Установочный скрипт zulip.sh падает на середине
Типичная картина: ./zulip.sh --hostname=chat.example.com --email=admin@example.com доходит до половины и обрывается с трейсбеком Python. Три причины закрывают 80% случаев.
Не та версия ОС. Zulip официально поддерживает Ubuntu 22.04/24.04 и Debian 12 — на более старых или экзотических дистрибутивах зависимости из репозитория не совпадают с тем, что ждёт скрипт. Проверьте версию перед стартом:
lsb_release -a
Локаль не установлена. Если в системе нет en_US.UTF-8, PostgreSQL и часть Python-зависимостей ругаются на кодировку прямо в процессе установки:
locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8
Скрипт запущен не от root или не тем пользователем. Установщик Zulip рассчитан на запуск от root на чистом сервере — если до этого на машине уже стоял свой PostgreSQL или Nginx на портах 80/443, конфликт версий и портов ломает установку. На новом VPS без наследия из старых пакетов таких коллизий не возникает — это самый быстрый способ избежать половины проблем разом.
Если установка упала на середине, повторный запуск zulip.sh часто ломается ещё сильнее из-за частично применённых миграций. Надёжнее — поднять новый сервер и повторить установку с исправленными вводными, чем чинить наполовину развёрнутую систему.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверОшибка при выпуске SSL-сертификата
Zulip встраивает Certbot в установочный процесс и по умолчанию сам выпускает Let's Encrypt сертификат на указанный --hostname. Ошибка Failed authorization procedure на этом шаге почти всегда означает одно: DNS A-запись домена ещё не смотрит на IP сервера, либо порт 80 закрыт файрволом на момент проверки challenge.
Проверка перед установкой:
dig +short chat.example.com
curl -I http://chat.example.com/.well-known/acme-challenge/test
Первая команда должна вернуть ровно IP вашего сервера — не CDN, не старый сервер, не proxy Cloudflare (оранжевое облако на этапе первого выпуска сертификата лучше отключить, вернуть после). Если DNS ещё не разошёлся, подождите распространения и запустите установку заново — Zulip не выпускает сертификат повторно автоматически при следующем старте сервисов, для ручного перевыпуска:
sudo -u zulip /home/zulip/deployments/current/scripts/setup/generate-self-signed-cert chat.example.com
# или через certbot напрямую после того как DNS поправлен
certbot certonly --webroot -w /var/lib/zulip/certbot-webroot -d chat.example.com
Общая логика проверки SSL и частые тонкости с challenge — в статье про настройку Let's Encrypt на VPS, она применима и здесь: те же ограничения на количество попыток и та же зависимость от корректного DNS до запроса сертификата.
RabbitMQ не стартует или очереди не разгребаются
Zulip использует RabbitMQ как шину сообщений между Django и фоновыми воркерами (отправка email, пуш-уведомления, индексация поиска). Если после установки сообщения "зависают" — печатаются в чат с задержкой в минуты вместо секунд, — почти всегда виноват RabbitMQ.
Проверка статуса и очередей:
sudo rabbitmqctl status
sudo rabbitmqctl list_queues name messages consumers
Если очереди растут, а consumers равен нулю — воркеры Zulip не подключены к брокеру. Обычно это происходит после смены hostname сервера без пересоздания RabbitMQ vhost, либо после ручной чистки /var/lib/rabbitmq без остановки службы:
sudo supervisorctl restart all
sudo systemctl restart rabbitmq-server
sudo supervisorctl status
В выводе supervisorctl status все процессы вида zulip-django, zulip-tornado, process-fts-updates, events_* должны быть в статусе RUNNING. Любой FATAL или постоянный STARTING — сигнал смотреть конкретный лог в /var/log/zulip/.
Redis в Zulip задействован под rate limiting и часть кэша сессий — при типичной установке отдельного тюнинга не требует, но если вы переносите его на выделенный контейнер или сервер, общие принципы настройки описаны в статье про установку и настройку Redis на VPS.
PostgreSQL: медленный поиск и ошибки при миграциях
Zulip держит полнотекстовый поиск на встроенных механизмах PostgreSQL (tsvector), поэтому база — не просто хранилище, а часть логики поиска. Две частые проблемы.
Поиск не находит свежие сообщения. Индекс полнотекстового поиска обновляется асинхронным процессом process_fts_updates — если он упал (см. предыдущий раздел про supervisor), новые сообщения физически лежат в базе, но не попадают в индекс. Решение — перезапустить процесс и, если отставание большое, дать ему время догнать очередь.
Ошибки при manage.py migrate после обновления. Если PostgreSQL стоит не той версии, что ожидает текущий релиз Zulip (проект обычно тестируется против одной-двух актуальных мажорных версий PostgreSQL), миграции могут падать на специфичных для версии функциях. Проверить версию:
sudo -u zulip psql -c "SELECT version();"
Общие принципы настройки самого PostgreSQL под нагрузку — буферы, shared_buffers, work_mem, автовакуум — не специфичны для Zulip и разобраны в статье про настройку PostgreSQL на VPS; для организации на 20-50 человек тюнинг по умолчанию обычно достаточен, ощутимо тюнить есть смысл начиная с активной истории на сотни тысяч сообщений.
Email-уведомления не приходят
Zulip шлёт уведомления о новых сообщениях, приглашениях и цифровые дайджесты по SMTP — если письма не уходят, а в веб-интерфейсе всё выглядит нормально, причина в /etc/zulip/settings.py. Проверьте, что там заданы EMAIL_HOST, EMAIL_HOST_USER, EMAIL_PORT, и что пароль лежит отдельно в /etc/zulip/zulip-secrets.conf под ключом email_password.
Быстрый тест отправки прямо из окружения Zulip:
sudo -u zulip /home/zulip/deployments/current/manage.py send_test_email you@example.com
Если тест падает с SMTPAuthenticationError — почти всегда дело в том, что почтовый провайдер требует пароль приложения, а не обычный пароль аккаунта (актуально для Gmail и большинства современных SMTP-сервисов с двухфакторной аутентификацией). Если письмо уходит через send_test_email, но реальные уведомления — нет, смотрите очередь email_mirror в RabbitMQ: возможно, воркер отправки не запущен, а не сам SMTP настроен неверно.
Отдельно стоит завести исходящий домен и SPF/DKIM-записи для него — без них письма Zulip будут стабильно улетать в спам у получателей на крупных почтовых сервисах, даже если SMTP настроен технически верно.
Обновление Zulip и откат при неудачном апгрейде
Обновление ставится тарболом через upgrade-zulip-from-git или upgrade-zulip, а не через apt — это отдельная точка отказа, если её не учитывать. Перед любым обновлением обязателен бэкап:
sudo -u zulip /home/zulip/deployments/current/manage.py backup
Это создаёт полный дамп: базу, аплоады, конфиги. Сам апгрейд:
sudo /home/zulip/deployments/current/scripts/upgrade-zulip zulip-server-X.Y.tar.gz
Если после обновления сервисы не поднимаются — Zulip хранит предыдущие деплои в /home/zulip/deployments/, и откат делается симлинком на предыдущую рабочую версию без восстановления из бэкапа:
ls /home/zulip/deployments/
sudo /home/zulip/deployments/<предыдущая-версия>/scripts/restart-server
К бэкапу из manage.py backup стоит прибегать, когда откат по симлинку невозможен — например, если проблема не в коде, а в уже применённых необратимых миграциях базы. Если планируете сравнивать Zulip с другими self-hosted мессенджерами для команды, у нас есть похожий разбор для установки Mattermost на VPS — модель обновлений там устроена похоже, но без тредовой структуры обсуждений, которая и есть главное отличие Zulip.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Сколько реально нужно RAM для Zulip на 15-20 человек?
Формально хватает 2 ГБ, но на практике с историей сообщений за несколько месяцев и активным поиском комфортнее 4 ГБ — 2 ГБ подходят скорее для пилота или теста перед переездом команды.
Можно ли ставить Zulip в Docker вместо zulip.sh?
Официально поддерживается путь через zulip.sh на голой Ubuntu/Debian; Docker-образ существует, но менее гибок при кастомной настройке SMTP, S3-хранилища аватаров и интеграций — для продакшена большинство админов выбирают классическую установку.
Что делать, если после установки не открывается веб-интерфейс, хотя supervisorctl status показывает всё RUNNING?
Проверьте Nginx: nginx -t на синтаксис конфига и curl -I http://localhost изнутри сервера. Часто причина — конфликт порта 80/443 с ранее установленным веб-сервером, который установщик Zulip не смог полностью подвинуть.
Нужен ли отдельный сервер под RabbitMQ и PostgreSQL при росте команды?
До нескольких сотен активных пользователей всё живёт на одном сервере без проблем; вынос базы и очереди на отдельные машины имеет смысл, когда упираетесь в CPU/IO конкретно одного из компонентов, а не заранее "про запас".
Как понять, что причина медленной работы — не сеть, а сервер?
Проверьте htop на пиковой нагрузке и rabbitmqctl list_queues на растущие очереди — если CPU/RAM свободны и очереди пустые, дело в сети или клиенте, а не в бэкенде Zulip.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →