Короткий ответ

zabbix-server не поднимается — не начинайте с «подкрутить StartPollers». Читайте /var/log/zabbix/zabbix_server.log и journalctl -u zabbix-server до первой фатальной строки: БД, синтаксис конфига, занятый 10051, права пользователя zabbix. Проверьте конфиг через zabbix_server -T, доступ к PostgreSQL/MySQL, сокет 10051. UI может жить отдельно на PHP и врать «server is not running», пока демон мёртв — это не повод чинить nginx. Фронт: Zabbix frontend не открывается.

Сервер в этой статье: zabbix.example, 10.0.20.50, пакеты 6.0 LTS или 7.0 LTS.

Симптомы и как отличить

Типичная картина:

  • systemctl status zabbix-serverfailed / activating (auto-restart);
  • на 10.0.20.50 нет LISTEN на 10051/tcp;
  • frontend открывается, баннер «Zabbix server is not running»;
  • агенты и proxy копят очередь, active checks отваливаются.

Отличия:

КартинаНе «сервер не стартует»Куда
Демон running, UI 502PHP/nginxFrontend
Running, очередь растётpollers/DB I/OОчередь
Running, диск БД пухнетhistoryБаза растёт
Proxy не шлётPSK/mode proxyProxy
Unit failed сразу после editэтот материаллог + -T

Возможные причины

  1. PostgreSQL/MySQL не слушает, неверные DBHost/DBName/DBUser/DBPassword, pg_hba отвергает zabbix.
  2. Ошибка в zabbix_server.conf после ручной правки (Include, кавычки, UTF-16, CR).
  3. Порт 10051 занят старым zabbix_server, чужим контейнером, leftover после kill -9.
  4. Нет прав на лог, pid, alertscripts; директории не принадлежат zabbix.
  5. Несовпадение схемы БД и бинаря (пакет 7.0 к базе 6.0 без schema upgrade).
  6. Disk full на /var/lib/postgresql или /var/log/zabbix — процесс стартует и умирает.
  7. Редко: AppArmor профиль, LimitNOFILE слишком низкий при огромном конфиге, HA VIP держит чужой инстанс на том же IP.

Диагностика

Все команды на 10.0.20.50, пока не доказано иное.

1. Unit и первая строка лога

systemctl status zabbix-server --no-pager -l
sudo journalctl -u zabbix-server -n 100 --no-pager
sudo tail -n 150 /var/log/zabbix/zabbix_server.log

Ищите Cannot connect to the database, unable to parse, bind, Permission denied. Дальше конфиг не трогайте, пока не воспроизведёте эту строку.

2. Проверка конфига без старта

Официальный флаг самопроверки — -T / --test-config (не путать с -t у агента):

sudo -u zabbix zabbix_server -c /etc/zabbix/zabbix_server.conf -T

Выход 0 и отсутствие parse error — синтаксис жив. Код ≠ 0 — исправляйте указанную строку, не соседние «оптимизации».

Посмотрите ключевые параметры:

sudo grep -E '^(DB|Listen|Log|Pid|Socket|User)=' /etc/zabbix/zabbix_server.conf | grep -v '^#'

3. Сокет 10051

ss -lntp | grep 10051
sudo lsof -iTCP:10051 -sTCP:LISTEN

Если слушает не zabbix_server — уберите чужой процесс. Второй инстанс из контейнера на том же host network — классика после «быстрого теста».

4. База

PostgreSQL (типичный путь 6.0/7.0):

sudo systemctl status postgresql --no-pager
sudo -u zabbix psql -h 127.0.0.1 -U zabbix -d zabbix -c 'SELECT 1;'

Пароль берётся из DBPassword или .pgpass пользователя zabbix. pg_hba.conf: метод для 127.0.0.1 должен пускать роль zabbix. Если DBHost=localhost идёт в Unix socket, а роль без peer — будет «Cannot connect», хотя TCP пароль верный.

Версия схемы vs пакет:

sudo -u zabbix psql -d zabbix -c "SELECT mandatory,optional FROM dbversion;"
zabbix_server -V

mandatory должен соответствовать мажорной линии установленного сервера. Расхождение после неудачного apt upgrade — частая причина мгновенного exit.

Место на диске:

df -h /var/lib/pgsql /var/lib/postgresql /var/log/zabbix / /var

5. Права pid и лога

ls -ld /var/log/zabbix /var/run/zabbix /run/zabbix
ls -l /etc/zabbix/zabbix_server.conf

Конфиг не должен быть world-writable. Лог — writable для zabbix.

Решение

Сценарий A. База недоступна

  1. Поднимите СУБД, дождитесь ready to accept connections.
  2. Проверьте DBHost, DBPort, DBName=zabbix, пользователя.
  3. Не меняйте пароль в трёх местах рассинхронно (сервер, frontend zabbix.conf.php, cron). Сначала сервер.
sudo systemctl start postgresql
sudo -u zabbix psql -h 127.0.0.1 -U zabbix -d zabbix -c 'SELECT now();'
sudo systemctl start zabbix-server

Если PostgreSQL слушает только socket, а в конфиге DBHost=10.0.20.50, либо поправьте listen_addresses, либо поставьте DBHost=127.0.0.1 согласованно с pg_hba.

Сценарий B. Конфиг не парсится

Верните backup файла. Проверьте Include:

sudo ls -l /etc/zabbix/zabbix_server.d/
sudo -u zabbix zabbix_server -c /etc/zabbix/zabbix_server.conf -T

Частые опечатки: StartPollers 100 без =, кириллическая С в ключе, BOM. Правится точечно.

Сценарий C. Порт 10051 занят

Найдите PID, убедитесь, что это не ваш же живой сервер (тогда unit врёт). Если зомби:

sudo systemctl stop zabbix-server
sudo pkill -u zabbix zabbix_server
ss -lntp | grep 10051
sudo systemctl start zabbix-server

pkill только после stop и только процессы пользователя zabbix, не пользовательские сессии.

Сценарий D. Схема не совпала с пакетом

Читайте release notes вашей линии 6.0.x / 7.0.x. Upgrade идёт через zabbix-sql-scripts и документированный cat ... | psql, после backup. Не накатывайте schema «с нуля». Если апгрейд прервался — не стартуйте дважды параллельно; смотрите лог на starting automatic database upgrade.

Сценарий E. Нет места / права

Освободите логи zabbix_server.log (rotate, не rm открытого inode без restart). Верните владельца:

sudo chown -R zabbix:zabbix /var/log/zabbix /run/zabbix
sudo systemctl restart zabbix-server

Housekeeper, который потом убивает I/O — отдельная тема: Housekeeper перегружает сервер. Сейчас цель — процесс в running.

Как проверить, что проблема устранена

systemctl status zabbix-server --no-pager
ss -lntp | grep 10051
sudo tail -n 30 /var/log/zabbix/zabbix_server.log
sudo -u zabbix zabbix_server -c /etc/zabbix/zabbix_server.conf -T

В логе: Zabbix Server stopped не должно появляться сразу после start. Должны быть строки старта процессов (poller, trapper, housekeeper). Frontend: баннер «not running» исчез. С агента WS-042 active path на 10.0.20.50:10051 снова получает конфиг (если используете active).

Простой функциональный тест trapper/poller: zabbix_get к агенту с сервера и свежий agent.ping в Latest data не обязателен для «демон жив», но обязателен для «мониторинг работает».

Если не помогло

  • Unit active, UI всё ещё «not running»: frontend смотрит на другой IP/сокет ($ZBX_SERVER / zabbix.conf.php), или кэш PHP. См. статью про frontend.
  • Старт и смерть через 30 с: смотрите OOM (dmesg | grep -i kill), не увеличивайте StartDBSyncers вслепую.
  • HA: два server с одной БД без documented HA 7.0 — классический split. Оставьте один writer.
  • Контейнер + host: разные zabbix_server.conf, вы правите не тот.
  • После смены DBPassword frontend жив, server нет — они не делят пароль автоматически.

Профилактика

  • Перед edit конфига: копия файла и zabbix_server -T.
  • Мониторинг самого zabbix-server с другого узла (внешний ICMP + 10051) или watchdog hypervisor, иначе смерть сервера не алертится.
  • Backup БД по расписанию, проверка restore. Рост базы — отдельная статья.
  • Апгрейд 6.0 → 7.0 только по checklist: backup, read notes, schema, потом пакет frontend.
  • Disk watermark на томе PostgreSQL и /var/log/zabbix.

FAQ

Чем zabbix_server -T отличается от запуска?

-T парсит конфиг и выходит, не поднимая pollers и не трогая БД (проверка синтаксиса/значений). Это безопасный шаг до systemctl start.

Можно ли Start=always и забыть?

Restart policy спрячет циклический crash. Смотрите NRestarts в systemctl status. Если >0 за минуту — вы не «починили», вы молотите диск логом.

Server в foreground для отладки?

zabbix_server -f -c /etc/zabbix/zabbix_server.conf на копии конфига, не на проде с двумя инстансами на одном порту. На проде достаточно лога.

Нужно ли чистить pid-файл вручную?

Если unit не стартует из-за stale pid — удаляйте только после systemctl stop и проверки, что процесса нет. Не rm pid «на всякий случай» у живого сервера.

MySQL вместо PostgreSQL — тот же алгоритм?

Да: лог → -T → коннект клиентом СУБД → порт 10051. Меняются только клиент (mysql) и имена опций грантов. Не мигрируйте СУБД как способ починить start.

После reboot unit failed, вручную start помогает?

Зависимость от PostgreSQL: в unit должно быть After=/Requires= на СУБД. Иначе race. Правится drop-in systemd, не @reboot sleep 30 в cron.