Zammad на сервере: частые ошибки и решения
Zammad редко падает целиком — обычно ломается что-то одно: поиск перестаёт находить тикеты, письма из почтового ящика не превращаются в заявки, интерфейс зависает на загрузке или контейнер zammad-railsserver уходит в перезапуск по кругу. Проблема в том, что Zammad — это связка из пяти-шести сервисов (Rails, Elasticsearch, PostgreSQL, Redis, Memcached, вебсокет-демон), и ошибка в логах одного часто на самом деле вызвана другим. Разберём конкретные симптомы и что с ними делать на реальном сервере.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Как устроен Zammad и где что смотреть
Если вы ставили Zammad через docker-compose (а сейчас это основной способ установки), стек выглядит так:
zammad-railsserver # веб-приложение и API
zammad-scheduler # фоновые задачи, cron внутри Zammad
zammad-websocket # real-time обновления в интерфейсе
zammad-nginx # отдаёт статику, проксирует в rails
zammad-elasticsearch # полнотекстовый поиск
zammad-postgresql # основная БД
zammad-redis # сессии, кэш
zammad-memcached # кэш приложения
Первое, что нужно сделать при любой проблеме — посмотреть, какой контейнер не в порядке:
docker compose ps
docker compose logs -f --tail=200 zammad-railsserver
Статус unhealthy или постоянный Restarting почти всегда указывает на конкретный сервис — дальше смотрим именно его логи, а не общий вывод. Если вы разворачивали стек вручную, полезно свериться с общими граблями Docker Compose в продакшене — там разбираются похожие сценарии рестартов и падений контейнеров: Docker Compose для продакшена на сервере: частые ошибки и решения.
Elasticsearch не запускается или падает
Самая частая причина отказа Zammad целиком — не сам Zammad, а Elasticsearch, от которого зависит поиск (а с недавних версий — и часть основных функций интерфейса, не только строка поиска). Типичная ошибка в логах:
max virtual memory areas vm.max_map_count [65530] is too low
Elasticsearch требует большего лимита на количество областей виртуальной памяти. Правится на хосте (не внутри контейнера):
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
Вторая частая беда — Elasticsearch съедает всю доступную память и его убивает OOM killer. По умолчанию JVM-куча настраивается на долю RAM хоста, и на маленьком VPS (2 ГБ и меньше) этого попросту не хватает на весь стек сразу. Смотрим:
dmesg | grep -i "killed process"
docker stats --no-stream
Если видите Killed process ... (java) — это Elasticsearch. Ограничьте кучу явно через переменную окружения в docker-compose.yml:
zammad-elasticsearch:
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
На VPS с 2 ГБ RAM Zammad с полным стеком работает на пределе — комфортный минимум для тестового инстанса 2 vCPU / 4 ГБ, для боевой поддержки с историей переписки — от 4 vCPU / 8 ГБ. Если сомневаетесь в объёме — проще сразу взять запас, чем потом мигрировать данные на больший сервер.
После правки лимитов переиндексируйте поиск — это стандартная команда Zammad, выполняется внутри контейнера rails:
docker compose run --rm zammad-railsserver rails r "Rebuild.all"
Процесс может занять от нескольких минут до пары часов в зависимости от объёма тикетов — не прерывайте его.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПисьма не превращаются в тикеты
Вторая по частоте жалоба — почта приходит на ящик, но заявки в Zammad не появляются. Проверяем по шагам.
Сначала — работает ли получение писем в принципе. В административной панели: Каналы → Email → Ваш аккаунт → Fetch now. Если при ручном запуске вылезает ошибка соединения — дело в самом почтовом сервере, а не в Zammad. Частые причины:
- неверный порт (993 для IMAPS, 143 для обычного IMAP без TLS — используйте первый);
- провайдер требует пароль приложения, а не основной пароль аккаунта (актуально для Gmail, Yandex, Mail.ru);
- фаервол на сервере блокирует исходящие подключения на порт 993.
Проверить соединение вручную с сервера:
openssl s_client -connect imap.example.com:993 -crlf
Если открывается TLS-сессия и виден банер * OK, соединение в порядке — проблема в логине или каталоге, откуда Zammad читает письма (обычно нужно указать именно INBOX, а не корень ящика).
Если вы сами держите почтовый сервер для Zammad на отдельном VPS (частый вариант — чтобы не зависеть от чужого SMTP), а не просто ящик у стороннего провайдера, полезно свериться с типовыми граблями postfix — там разбираются похожие ситуации с доставкой и очередями: Почтовый сервер Postfix на сервере: частые ошибки и решения.
Второй момент — фильтры Zammad могут молча отбрасывать письма ещё до создания тикета (правило X-Zammad-Ignore или пользовательский триггер с условием if email is not new). Проверьте Manage → Trigger на предмет условий, которые случайно перехватывают входящую почту.
Третья причина, о которой часто забывают — постановка письма в очередь через zammad-scheduler. Если контейнер scheduler не поднят или упал, письма формально забираются с сервера, но в тикеты не превращаются. Смотрите его логи отдельно:
docker compose logs -f zammad-scheduler
Интерфейс зависает на загрузке или "белый экран"
Если после логина открывается пустая страница или бесконечный спиннер — почти всегда виноват вебсокет-сервис или обратный прокси перед Zammad, который не пробрасывает апгрейд соединения до WebSocket.
В консоли браузера (F12 → Network → фильтр WS) смотрите на подключение к /ws. Если оно падает с ошибкой 400 или 502 — прокси перед Zammad не настроен на Upgrade/Connection заголовки. Для Nginx перед Zammad (если вы ставите свой прокси вместо встроенного контейнера zammad-nginx) нужен такой блок:
location /ws {
proxy_pass http://127.0.0.1:6042;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
Без proxy_read_timeout соединение обрывается через стандартные 60 секунд простоя, и интерфейс будет то работать, то замирать — характерный симптом, который легко спутать с багом самого Zammad. Если у вас в принципе бывают проблемы с применением SSL и конфигов на Nginx перед бэкендами — разбор похожих ситуаций здесь: Nginx не применяет SSL: причины и решение.
Второй вариант белого экрана — контейнер zammad-railsserver не прошёл миграции после обновления и завис в промежуточном состоянии. Проверка:
docker compose exec zammad-railsserver rails r "puts ActiveRecord::Migrator.current_version"
Если команда падает с ошибкой о несовпадении версий схемы — читайте раздел про миграции ниже.
Ошибки при обновлении и миграциях базы
Zammad довольно требователен к порядку обновления: нельзя перепрыгивать через несколько мажорных версий за один раз, и перед обновлением обязателен бэкап — как файлов, так и базы. Стандартная последовательность для Docker-инсталляции:
docker compose down
docker compose pull
docker compose up -d
docker compose logs -f zammad-railsserver
При старте после pull railsserver сам прогоняет миграции — это нормально, процесс может занимать несколько минут на базе с большой историей тикетов. Проблема начинается, если миграция обрывается на середине (например, кончилось место на диске или контейнер убили по таймауту). Тогда база оказывается в промежуточном состоянии, и повторный up -d падает с ошибкой вида:
PG::UndefinedColumn: ERROR: column "..." does not exist
В этой ситуации не пытайтесь чинить руками через SQL — правильный путь: остановить стек, восстановить PostgreSQL из бэкапа, снятого до начала обновления, и повторить обновление уже с запасом места на диске и без принудительного обрыва контейнера. Общие принципы восстановления БД из бэкапа, применимые и к базе Zammad, разобраны здесь: Восстановление базы данных из бэкапа: практика.
Перед любым обновлением обязательно проверяйте свободное место — миграции с полнотекстовым переиндексированием и дампы БД временно требуют заметно больше места, чем занимает сама база:
df -h
docker system df
Медленная работа и нехватка ресурсов
Если Zammad технически работает, но интерфейс тормозит, а поиск отвечает по 5-10 секунд — почти всегда дело в ресурсах, а не в конфигурации. Проверьте, во что упирается сервер:
docker stats --no-stream
free -h
vmstat 1 5
Частая ситуация на VPS с 2 ГБ RAM: Elasticsearch и PostgreSQL вместе выедают всю память, система уходит в своп, и всё резко замедляется. Если совсем убрать своп нельзя (полностью выключенный своп при внезапном скачке памяти = OOM-killer убивает случайный процесс), но и держать его слишком большим на медленном диске VPS тоже не стоит — ориентир и настройка описаны здесь: Swap-файл: когда нужен и как настроить и Правильный размер swap для VPS.
Практический ориентир по ресурсам под Zammad (именно ориентир — у вас будет зависеть от числа агентов, объёма истории и активности API):
| Сценарий | vCPU | RAM | Диск |
|---|---|---|---|
| Тест / 1-2 агента | 2 | 4 ГБ | 40 ГБ SSD |
| Небольшая команда, до 10 агентов | 2-4 | 8 ГБ | 60-80 ГБ SSD |
| Активная поддержка, 10+ агентов, вложения | 4-6 | 16 ГБ | 100+ ГБ SSD |
Диск важен не меньше памяти: вложения к тикетам и индекс Elasticsearch растут быстро. Если PostgreSQL под нагрузкой сам становится узким местом (долгие запросы, блокировки) — отдельный разбор тюнинга здесь: Тюнинг PostgreSQL на сервере: частые ошибки и решения.
Резервное копирование и восстановление
Zammad хранит состояние в двух местах: PostgreSQL (тикеты, пользователи, настройки) и файловая система (вложения, если не вынесены в S3-совместимое хранилище). Бэкапить нужно оба, причём согласованно по времени — иначе после восстановления вложения могут не совпадать с записями о них в базе.
Минимальный рабочий вариант через docker compose exec:
# дамп базы
docker compose exec zammad-postgresql pg_dump -U zammad zammad > zammad_db_$(date +%F).sql
# архив с данными приложения (вложения, конфиги)
docker run --rm --volumes-from zammad-railsserver \
-v $(pwd)/backups:/backup alpine \
tar czf /backup/zammad_data_$(date +%F).tar.gz /opt/zammad/storage
Оба файла имеет смысл сразу же копировать за пределы сервера (на S3, другой VPS или локальную машину) — бэкап рядом с тем же диском, который может выйти из строя, не защищает ни от чего. Общие практики бэкапа Docker-томов, применимые и к volume Zammad, здесь: Бэкап Docker volume на сервере: частые ошибки и решения.
Восстановление — в обратном порядке: сначала поднимаете zammad-postgresql и заливаете дамп, затем распаковываете архив данных в нужный volume, и только потом стартуете остальной стек. Запускать zammad-railsserver раньше, чем восстановлена база, бессмысленно — он упадёт на старте или создаст пустую схему, поверх которой дамп уже не накатится штатно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Zammad вообще требует Elasticsearch, или можно без него?
Формально в старых версиях можно было отключить поиск и работать без Elasticsearch, но в современных релизах он используется не только для поиска, а и для части основного функционала интерфейса — отключать его не рекомендуется, проще выделить ему достаточно памяти.
Можно ли поставить Zammad не через Docker, а из пакетов дистрибутива?
Да, есть официальные пакеты под Ubuntu/Debian/CentOS, но большинство актуальной документации и сообщества сейчас ориентировано на Docker Compose — на нём проще воспроизводить проблему и катать обновления, поэтому в статье разобран именно этот сценарий.
После обновления пропали кастомные поля или триггеры — что делать?
Обычно это не потеря данных, а следствие незавершённой миграции или ошибки при импорте настроек. Проверьте логи zammad-railsserver на предмет ошибок миграции и восстановите базу из бэкапа, снятого перед обновлением, вместо попыток чинить состояние вручную.
Сколько тикетов и агентов реально держит VPS с 4 ГБ RAM?
Ориентировочно — команда до 5-7 агентов и несколько тысяч тикетов в истории; конкретика сильно зависит от того, сколько вложений проходит через систему и насколько активно используется поиск, поэтому лучше закладывать запас с самого начала, чем упираться в лимиты и переезжать на больший сервер под нагрузкой.
Нужен ли отдельный SSL-сертификат, если Zammad уже идёт со встроенным Nginx?
Встроенный контейнер zammad-nginx отдаёт только HTTP; сертификат для HTTPS нужно настраивать либо через ваш собственный обратный прокси перед ним, либо через встроенную поддержку Let's Encrypt, если она включена в вашей версии — если сертификат перестаёт обновляться, типичные причины разобраны здесь: SSL-сертификат не обновился.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →