Sentry (self-hosted) на сервере: частые ошибки и решения
Self-hosted Sentry — это не «поднял контейнер и работает», а полноценный стек из десятка сервисов: Kafka, ClickHouse, Postgres, Redis, Snuba, Symbolicator, Relay. Каждый из них может упасть по своей причине, и типичная картина после docker compose up — часть контейнеров в вечном restart, а веб-интерфейс отдаёт 502. Разберём конкретные ошибки self-hosted Sentry на сервере, с чем они связаны и как их закрывать — без общих советов «перезапустите и подождите».
Содержание
- Сколько реально нужно ресурсов
- Контейнеры падают в цикл restart сразу после установки
- ClickHouse и Snuba: главный источник проблем в проде
- Sentry за reverse-proxy: 400 Bad Request и битые ссылки в письмах
- Почта не уходит: уведомления и приглашения не приходят
- Обновление self-hosted Sentry: почему ломается на миграциях
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Сколько реально нужно ресурсов
Официальный install-скрипт getsentry/self-hosted проверяет ресурсы перед установкой и отказывается стартовать на слабой машине — это не прихоть, а следствие архитектуры: ClickHouse и Kafka сами по себе прожорливы, а рядом с ними крутятся ещё Postgres, Redis, Snuba consumers, symbolicator и nginx-фронт.
Ориентир из документации проекта (у вас цифры могут отличаться в зависимости от нагрузки и числа проектов):
| Ресурс | Минимум | Комфортно для продакшена |
|---|---|---|
| CPU | 4 vCPU | 8 vCPU |
| RAM | 16 ГБ | 24-32 ГБ |
| Диск | 30 ГБ SSD | 100+ ГБ SSD (события и трейсы растут быстро) |
| Docker | Compose 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-консьюмеры Snuba | docker compose logs snuba-consumer, лаг в топиках Kafka |
Ошибка Too many parts в логах ClickHouse | Диск не успевает мержить вставки, обычно из-за медленного I/O | docker 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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →