Zulip на Ubuntu 24.04: пошаговая установка
Команда выросла — и общий чат в Telegram превратился в свалку из десятка параллельных тем: важное сообщение тонет в потоке уже через пять минут после публикации, а найти вчерашнее обсуждение почти нереально. Zulip решает это тредовой моделью: каждая тема живёт отдельной веткой внутри канала, и вернуться к разговору недельной давности так же просто, как открыть нужную папку. Ниже — пошаговая установка Zulip на чистый сервер с Ubuntu 24.04: от подготовки DNS до первого администратора организации.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Zulip и тредовая модель: чем это лучше линейной ленты
В Slack, Mattermost или Rocket.Chat сообщения в канале идут одной непрерывной лентой. Если в канале одновременно обсуждают деплой, баг в проде и заказ пиццы на пятницу — все три разговора перемешиваются в хронологическом порядке, и участнику приходится вручную отделять одно от другого.
Zulip организует канал как набор именованных тем (topics). Каждое новое обсуждение — это либо продолжение существующей темы, либо новая тема с собственным заголовком. Визуально это ближе к почтовому клиенту с папками, чем к мессенджеру: слева список каналов и тем, справа — переписка внутри выбранной темы.
Что это даёт на практике:
- Асинхронная работа без потерь контекста. Человек, который не был онлайн два дня, открывает список непрочитанных тем, а не листает ленту на 500 сообщений назад.
- Поиск и навигация работают предсказуемо. Тема "Деплой 27 августа" остаётся темой даже спустя месяц, её легко найти и процитировать.
- Меньше шума для тех, кто не в теме. Можно подписаться на канал, но приглушить неинтересные темы внутри него — в отличие от плоской ленты, где выбор только "весь канал или ничего".
Обратная сторона — более крутая кривая привыкания. Новым участникам первую неделю непривычно, что нужно явно указывать тему при каждом сообщении, а не просто писать "в канал". Для команд до 5-7 человек с одним общим потоком задач разница со Slack-подобным интерфейсом не так ощутима — там может быть удобнее Mattermost или Rocket.Chat. Zulip раскрывается на командах от 15-20 человек и больше, особенно распределённых по часовым поясам, где сообщения читают не в реальном времени, а пачками.
Что подготовить перед установкой
Официальный установщик Zulip — это единый bash-скрипт, который сам разворачивает PostgreSQL, RabbitMQ, Redis, Memcached и nginx на одном сервере, без ручной настройки каждого компонента. Это отличается, например, от классической установки Mattermost, где базу данных чаще поднимают отдельно. Но именно поэтому важно подготовить входные данные заранее — переустанавливать отдельные куски сложнее, чем перезапустить весь процесс.
Понадобится:
- Домен или поддомен, указывающий A-записью на IP сервера — например,
chat.example.com. Официальный скрипт установки умеет сразу выпускать сертификат Let's Encrypt через certbot, но для этого DNS должен успеть прогреться *до* запуска установки. - Ubuntu 24.04 LTS x86_64 с root-доступом или sudo без пароля.
- Открытые порты 80 и 443 — 80 нужен для HTTP-01 challenge certbot, 443 — для самого чата.
- Свободные ресурсы, ориентировочно (это не измеренные бенчмарки, а грубая прикидка под вашу нагрузку — проверяйте по факту):
| Размер команды | CPU | RAM | Диск |
|---|---|---|---|
| до 10 человек | 2 vCPU | 2-4 ГБ | 20 ГБ |
| 10-50 человек | 2-4 vCPU | 4-8 ГБ | 40 ГБ |
| 100+ человек | 4+ vCPU | 8-16 ГБ | 80+ ГБ |
На сервере с 2 ГБ RAM установщик может упереться в память на этапе сборки ассетов — ниже расскажу, как подстраховаться файлом подкачки.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПодготовка сервера: обновления, локаль, файл подкачки
Подключаемся по SSH и обновляем систему:
sudo apt update && sudo apt upgrade -y
sudo reboot
Zulip требует, чтобы в системе была сгенерирована UTF-8 локаль — на свежих минимальных образах Ubuntu она иногда отсутствует, и установщик падает на этом шаге с невнятной ошибкой. Проверяем и генерируем на всякий случай:
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8
Если у сервера меньше 4 ГБ RAM, добавляем файл подкачки — установка компилирует часть JS-ассетов, и без свопа процесс может быть убит OOM killer'ом на середине:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Настраиваем firewall — открываем только SSH, HTTP и HTTPS (подробный разбор правил — в статье про настройку ufw на Ubuntu 24.04):
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Проверяем, что DNS уже смотрит на сервер, прежде чем идти дальше:
dig +short chat.example.com
Команда должна вернуть IP вашего сервера. Если возвращает пусто или старый адрес — подождите распространения записи, иначе certbot на следующем шаге не сможет подтвердить домен.
Установка Zulip: скачивание и запуск инсталлятора
Скачиваем актуальный релиз с официального сервера раздачи — скрипт сам подтянет последнюю стабильную версию:
curl -fLO https://download.zulip.com/server/zulip-server-latest.tar.gz
tar -xf zulip-server-latest.tar.gz
Запускаем установку с автоматическим выпуском сертификата Let's Encrypt. Замените email и hostname на свои:
sudo ./zulip-server-*/scripts/setup/install \
--certbot \
--email=admin@example.com \
--hostname=chat.example.com
Процесс займёт от 10 до 30 минут в зависимости от мощности сервера — скрипт ставит зависимости из apt, разворачивает PostgreSQL и RabbitMQ, настраивает Redis и Memcached для кэширования и очередей, конфигурирует nginx как фронтенд с уже выпущенным TLS-сертификатом, и запускает миграции базы.
Если у вас уже есть nginx на сервере под другие сайты — это конфликт: установщик Zulip ожидает управлять nginx единолично. Для такого случая проще держать Zulip на отдельном сервере или поддомене с собственным IP, а не делить nginx между несколькими приложениями вручную.
Если сертификат по каким-то причинам не выпустился с первого раза (не успел прогреться DNS, порт 80 занят чем-то ещё) — можно переустановить только certbot-часть после устранения причины, не переигрывая всю установку заново; логика подтверждения домена та же, что и в общих случаях проблем с продлением сертификата.
По завершении скрипт выведет сообщение об успехе и напомнит следующий шаг — создание организации.
Первый запуск: создание организации и администратора
Zulip не создаёт организацию и учётку администратора автоматически — это осознанный шаг безопасности, чтобы случайный человек не мог зарегистрироваться первым и получить админку. Генерируем одноразовую ссылку для создания организации:
su zulip -c '/home/zulip/deployments/current/manage.py generate_realm_creation_link'
Команда выведет URL вида https://chat.example.com/new/<токен>. Открываем его в браузере — откроется форма:
- Название организации и её URL-префикс (или корневой домен, если организация будет единственной на сервере).
- Email и пароль первого администратора.
- Базовые настройки: разрешить ли открытую регистрацию, требовать ли приглашение, часовой пояс по умолчанию.
После заполнения формы вы окажетесь в рабочем интерфейсе Zulip уже под своей учёткой администратора. Дальше через /organization в веб-интерфейсе настраиваются каналы, роли пользователей, интеграции (GitHub, Jira, Sentry и десятки других через встроенные webhook-боты) и политика регистрации новых участников.
Почта, бэкапы и обновление Zulip
SMTP для писем. Без настроенной почты не будут приходить приглашения и уведомления о пропущенных сообщениях. Открываем /etc/zulip/settings.py, находим блок Outgoing email и заполняем:
EMAIL_HOST = 'smtp.example.com'
EMAIL_HOST_USER = 'zulip@example.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
Пароль от почтового ящика хранится отдельно от основного конфига — в секретах:
sudo nano /etc/zulip/zulip-secrets.conf
# добавить строку:
# email_password = ваш_пароль_или_app-пароль
Применяем изменения:
su zulip -c '/home/zulip/deployments/current/scripts/restart-server'
Резервное копирование. Встроенная команда собирает единый архив: дамп PostgreSQL, загруженные файлы (аватары, вложения), настройки и секреты:
su zulip -c '/home/zulip/deployments/current/manage.py backup'
Архив создаётся в /home/zulip/backups/. Заберите его копию на другой сервер или в объектное хранилище — бэкап, лежащий на том же диске, что и рабочая система, не спасает при отказе диска целиком. Поставьте команду в cron с ротацией старых архивов, если делаете бэкапы ежедневно вручную, а не через отдельный сервис резервного копирования.
Обновление. Zulip обновляется без даунтайма для пользователей (сессии переподключаются автоматически). Скачиваем новый релиз и передаём его существующей инсталляции:
curl -fLO https://download.zulip.com/server/zulip-server-latest.tar.gz
sudo /home/zulip/deployments/current/scripts/upgrade-zulip zulip-server-latest.tar.gz
Перед крупным обновлением (major-версия) стоит сделать свежий бэкап и проверить changelog на breaking changes — как и с любым продакшн-сервисом.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли поставить Zulip в Docker вместо нативной установки на Ubuntu?
Официально поддерживаемый способ для продакшена — именно установочный скрипт на Ubuntu/Debian, он же проще в обслуживании: бэкапы, апгрейды и диагностика заточены под эту схему. Docker-образ существует, но команда Zulip явно рекомендует его для разработки и тестирования, а не как основной способ деплоя на боевом сервере.
Сколько реально нужно RAM для команды из 30-40 человек?
Однозначного числа никто не даст — зависит от активности переписки, числа интеграций-ботов и истории сообщений. Ориентируйтесь на 4-8 ГБ как стартовую точку и следите за free -h и логами в /var/log/zulip/ первую неделю — если swap не используется под нагрузкой, ресурсов достаточно.
Установщик упал с ошибкой про certbot — что делать?
Почти всегда причина в DNS: A-запись ещё не разрешается в IP сервера, или порт 80 занят другим процессом. Проверьте dig +short ваш_домен и sudo ss -tlnp | grep :80, устраните причину и перезапустите установку тем же скриптом — он идемпотентен и продолжит с прерванного места.
Нужен ли отдельный сервер под Zulip, если уже есть Mattermost или Rocket.Chat на этой машине?
Да, желательно. Установщик Zulip хочет единолично управлять nginx и системными сервисами на порту 80/443, что конфликтует с любым другим приложением, уже занявшим эти порты. Разделять веб-приложения на разные VPS проще, чем разруливать конфликты одного nginx между несколькими стеками.
Как перенести Zulip на другой сервер?
Через тот же встроенный бэкап: manage.py backup на старом сервере, перенос архива, установка чистого Zulip на новом сервере тем же скриптом и восстановление командой scripts/setup/restore-backup путь_к_архиву. Это надёжнее, чем копировать файлы вручную, потому что архив уже содержит согласованный дамп базы и все секреты.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →