MAATRIX / Блог / Sentry (self-hosted) на сервере: частые ошибки и решения

Sentry (self-hosted) на сервере: частые ошибки и решения

MAATRIX

Self-hosted Sentry — это не «поднял контейнер и работает», а полноценный стек из десятка сервисов: Kafka, ClickHouse, Postgres, Redis, Snuba, Symbolicator, Relay. Каждый из них может упасть по своей причине, и типичная картина после docker compose up — часть контейнеров в вечном restart, а веб-интерфейс отдаёт 502. Разберём конкретные ошибки self-hosted Sentry на сервере, с чем они связаны и как их закрывать — без общих советов «перезапустите и подождите».

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Сколько реально нужно ресурсов

Официальный install-скрипт getsentry/self-hosted проверяет ресурсы перед установкой и отказывается стартовать на слабой машине — это не прихоть, а следствие архитектуры: ClickHouse и Kafka сами по себе прожорливы, а рядом с ними крутятся ещё Postgres, Redis, Snuba consumers, symbolicator и nginx-фронт.

Ориентир из документации проекта (у вас цифры могут отличаться в зависимости от нагрузки и числа проектов):

РесурсМинимумКомфортно для продакшена
CPU4 vCPU8 vCPU
RAM16 ГБ24-32 ГБ
Диск30 ГБ SSD100+ ГБ SSD (события и трейсы растут быстро)
DockerCompose v2, свежий Docker Engine

На связке 2 CPU / 4 ГБ RAM install-скрипт либо сразу упадёт с понятной ошибкой о нехватке ресурсов, либо стартует, но ClickHouse и Kafka начнут убиваться OOM Killer'ом по очереди — в docker compose ps это выглядит как бесконечный Restarting. Если проект небольшой и такой стек избыточен, часто разумнее взять облачный Sentry или более лёгкий трекер ошибок, а self-hosted разворачивать на сервере, где 16+ ГБ памяти не проблема — под такую нагрузку обычно берут выделенный сервер, а не бюджетный VPS.

Контейнеры падают в цикл restart сразу после установки

Первое, что нужно смотреть — не общий статус, а логи конкретного упавшего сервиса:

docker compose ps
docker compose logs --tail=100 clickhouse
docker compose logs --tail=100 kafka
docker compose logs --tail=100 snuba-api

Три самые частые причины на этом этапе:

  • vm.max_map_count слишком маленький. ClickHouse и Kafka используют много memory-mapped файлов, и ядро с дефолтным лимитом (обычно 65530) не даёт им открыться — в логах будет что-то вроде max virtual memory areas vm.max_map_count is too low. Фикс постоянный:
echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
  • Нехватка памяти у Kafka. JVM-процесс Kafka по умолчанию резервирует фиксированную кучу и не подстраивается под маленький контейнер — при недостатке RAM он либо не стартует, либо падает под первой же нагрузкой. Смотрите dmesg | grep -i "out of memory" — если ядро действительно убило процесс по OOM, это не баг конфигурации Sentry, а нехватка ресурсов сервера.
  • Гонка при первом старте. Snuba и web пытаются подключиться к Postgres/ClickHouse/Kafka до того, как те успели инициализироваться и применить миграции. depends_on в docker-compose гарантирует только порядок запуска контейнера, а не готовность сервиса внутри — поэтому первый docker compose up -d иногда стоит просто повторить через минуту-две после того, как база и Kafka окончательно поднимутся.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

ClickHouse и Snuba: главный источник проблем в проде

Когда установка прошла, но через недели-месяцы начинает сбоить приём событий — почти всегда виноваты ClickHouse или Snuba-консьюмеры, а не сам Sentry.

Типичные симптомы и что за ними стоит:

СимптомВероятная причинаЧто проверить
События приходят с большой задержкой или не приходят вовсеОтстают Kafka-консьюмеры Snubadocker compose logs snuba-consumer, лаг в топиках Kafka
Ошибка Too many parts в логах ClickHouseДиск не успевает мержить вставки, обычно из-за медленного I/Odocker compose exec clickhouse clickhouse-client -q "SELECT table, count() FROM system.parts GROUP BY table ORDER BY count() DESC"
Диск неожиданно кончилсяНе работает автоочистка старых событийПроверьте, что запущен sentry-cleanup (cron-контейнер), и вручную: docker compose run --rm sentry-cleanup
snuba-api отдаёт 500 на поиск событийРассинхрон схемы ClickHouse после недоведённого апгрейдаСмотрите миграции: docker compose run --rm snuba-api snuba migrations list

Отдельно стоит держать в голове: ClickHouse чувствителен к качеству диска. На медленном или сильно нагруженном сетевом диске мержи не успевают за вставками, и Too many parts будет повторяться систематически — здесь помогает не тюнинг конфигов, а перенос на сервер с NVMe. Если у вас уже стоит мониторинг диска на сервере, полезно отдельно следить за разделом с данными ClickHouse — он растёт заметно быстрее остальных.

Sentry за reverse-proxy: 400 Bad Request и битые ссылки в письмах

Self-hosted Sentry поднимает собственный nginx-контейнер, слушающий локально (обычно 127.0.0.1:9000), а перед ним обычно ставят внешний nginx или Caddy с TLS. Если этот шаг сделан не до конца, вылезает пачка характерных ошибок:

  • 400 Bad Request на все запросы. Sentry сверяет заголовок Host с тем, что прописано в system.url-prefix внутри sentry/config.yml. Если внешний прокси не проксирует правильный Host или system.url-prefix указывает на http://localhost, а реальный домен другой — получите отказ. Правьте config.yml:
system.url-prefix: 'https://sentry.example.com'

и в блоке прокси обязательно передавайте заголовки:

location / {
    proxy_pass http://127.0.0.1:9000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  • Ссылки в email-уведомлениях ведут на http://localhost или на внутренний IP. Причина та же — system.url-prefix не поменяли после установки, Sentry берёт его дефолтное значение из install-скрипта.
  • CSRF-ошибка при логине через внешний домен. Нужно убедиться, что X-Forwarded-Proto: https реально доходит до контейнера — иначе Django-часть Sentry считает соединение нешифрованным и режет запрос.

После правки config.yml изменения применяются рестартом веб-сервиса: docker compose restart web worker. Если вы разворачивали SSL через Let's Encrypt перед этим reverse-proxy, часть смежных проблем разобрана в статье про частые ошибки Let's Encrypt на сервере.

Почта не уходит: уведомления и приглашения не приходят

Уведомления об ошибках — половина смысла Sentry, и почта здесь настраивается отдельно от остального стека, в блоке mail файла sentry/config.yml:

mail.backend: 'smtp'
mail.host: 'smtp.yourprovider.com'
mail.port: 587
mail.username: 'sentry@example.com'
mail.password: 'app-password'
mail.use-tls: true
mail.from: 'sentry@example.com'

После правки — перезапуск web и worker (именно worker шлёт письма асинхронно через Celery). Проверить, что почта реально отправляется, можно без ожидания реальной ошибки в проекте:

docker compose run --rm web sentry django sendtestemail admin@example.com

Если тестовое письмо не пришло — сначала смотрите логи worker, а не web: отправка идёт через очередь задач, и ошибка SMTP-авторизации часто видна только там. Отдельная частая ловушка — почтовые провайдеры блокируют исходящие с IP облачных VPS без настроенных SPF/DKIM/PTR-записей: письмо формально «отправлено», но падает в спам или отклоняется получателем. Если у сервера нет обратной PTR-записи на IP, часть провайдеров (особенно корпоративные) будет молча резать такие письма — это стоит проверить в первую очередь, прежде чем менять конфиг Sentry ещё раз.

Обновление self-hosted Sentry: почему ломается на миграциях

Self-hosted Sentry обновляется через тот же install-скрипт (./install.sh), и именно на апгрейде теряется больше всего времени — потому что миграции ClickHouse и Postgres должны применяться строго последовательно, без пропуска версий.

Правила, которые реально спасают от простоя:

  • Не перепрыгивайте через мажорные версии. Если между текущей и целевой версией было несколько релизов с изменениями схемы, апгрейд «через одну» ломает миграции Snuba непредсказуемо. Идите по документированному пути обновления шаг за шагом.
  • Бэкап перед каждым апгрейдом — не опция. В комплекте есть ./sentry-admin.sh для бэкапа и восстановления Postgres-данных; прогоните его перед запуском install.sh, а не после того, как что-то пошло не так.
  • Не используйте docker compose down --volumes для «чистого перезапуска». Это удаляет тома с данными ClickHouse и Postgres безвозвратно — обычный docker compose down (без --volumes) и docker compose up -d достаточны для рестарта без потери данных.
  • Если апгрейд оборвался на миграции — не запускайте install.sh повторно вслепую. Сначала посмотрите, на каком шаге упало (install.sh выводит номер шага и логи), почините конкретную причину (чаще всего — нехватка памяти при пересчёте данных ClickHouse) и только потом продолжайте.

Апгрейды такого стека — ещё один довод в пользу сервера с запасом по ресурсам: миграции ClickHouse на боевых данных временно удваивают нагрузку на диск и память, и если сервер и без апгрейда работает впритык, именно в этот момент всё и падает.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько RAM реально нужно для self-hosted Sentry в проде?

Официальный минимум — 16 ГБ, и это не запас, а рабочая точка: ClickHouse, Kafka и Postgres одновременно держат данные в памяти. На 8 ГБ стек либо не запустится, либо будет падать под первой ощутимой нагрузкой.

Можно ли уменьшить стек, убрав Kafka или ClickHouse?

В официальной поставке — нет, они часть архитектуры приёма и хранения событий. Урезанные схемы существуют в сторонних форках, но это уже не тот self-hosted Sentry, который поддерживает апстрим, и обновлять его сложнее.

Почему события долго не появляются в интерфейсе, хотя SDK шлёт их без ошибок?

Обычно отстают Kafka-консьюмеры Snuba — проверьте лаг и логи snuba-consumer, snuba-outcomes-consumer. Это чаще следствие нехватки CPU, чем сетевой проблемы.

Стоит ли ставить self-hosted Sentry на тот же сервер, где крутится продакшен-приложение?

Технически можно, но стек сам по себе съедает 16+ ГБ и заметно грузит диск — лучше выносить его на отдельный сервер, чтобы всплеск нагрузки на ClickHouse не задевал основное приложение.

Как понять, что причина — именно диск, а не память?

Смотрите dmesg на предмет OOM-убийств и отдельно df -h по разделу с данными ClickHouse (обычно sentry-clickhouse том). Если место не кончилось, а Too many parts всё равно есть — упирается именно в скорость записи, не в объём.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →