В среду 6 мая в 11:34 пришёл алерт от Uptime Kuma: 2bdgroup.com отдаёт 504 Gateway Timeout на главной странице. Сайт корпоративного клиента, B2B-услуги. Терять трафик в рабочее время — больно.
Через 47 минут сайт отдавал 200 OK за 0.28 секунды. Эта статья — про что произошло, как нашли причину, и что починили.
Симптомы
Главная страница 2bdgroup.com/ загружалась 10-19 секунд, периодически отдавая 504. Раздел /press-center/ — то же самое. Боты-краулеры (Bytespider, TikTokSpider, YandexBot) забивали FPM-очередь, новые запросы вылетали по таймауту Traefik (30 секунд).
Из логов nginx:
# Топ-5 user-agents за последний час до инцидента
$ tail -10000 /var/log/nginx/access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn | head -5
3421 Mozilla/5.0 (compatible; Bytespider; spider-feedback@bytedance.com)
1847 Mozilla/5.0 (compatible; TikTokSpider/1.0)
1102 Mozilla/5.0 (compatible; YandexBot/3.0)
421 Mozilla/5.0 (compatible; SemrushBot/7~bl)
387 Mozilla/5.0 (compatible; AhrefsBot/7.0)
5 ботов, 7000+ запросов в час. На 5 FPM-воркеров. Простая математика — мы покойники.
Root cause
Залезли в docker-compose.yml Coolify-стэка. Увидели дефолтный конфиг:
# php.ini до фикса
opcache.enable=0
pm.max_children=5
realpath_cache_size=16K
apc.shm_size=32M
OPcache выключен. На каждый HTTP-запрос PHP парсил ~10 000 файлов Bitrix Core. Главная отдавалась 10-19 секунд просто потому что PHP читал файлы с диска, парсил AST, исполнял.
Боты пришли — добили оставшиеся ресурсы.
<div class="bp-callout bp-callout-warning"><div class="bp-callout-label">warning</div><p>OPcache выключен на проде с Bitrix — это <strong>первый признак</strong> что сайт делал не специалист. Bitrix без opcache — это как Postgres с <code>fsync=off</code>: работает в dev, на проде убивается за день.</p> </div>
Что починили
Переписали env-vars в Coolify-стэке:
environment:
# OPcache на максимум
php.opcache.enable: '1'
php.opcache.enable_cli: '1'
php.opcache.memory_consumption: '512'
php.opcache.interned_strings_buffer: '32'
php.opcache.max_accelerated_files: '50000'
# Realpath cache — для файлового lookup
php.realpath_cache_size: '4096k'
php.realpath_cache_ttl: '600'
# APCu — для пользовательского кеша Bitrix
php.apc.enabled: '1'
php.apc.shm_size: '128M'
# FPM пул — выдержит bot-storm
FPM_PM_MAX_CHILDREN: '40'
FPM_PM_START_SERVERS: '20'
FPM_PM_MIN_SPARE_SERVERS: '10'
FPM_PM_MAX_SPARE_SERVERS: '30'
FPM_PM_MAX_REQUESTS: '500'
После перезапуска контейнера — скорость выросла в 60 раз:
| Метрика | Было | Стало |
|---|---|---|
| TTFB главной | 19.1 секунды | 0.28 секунды |
| TTFB /press-center/ | 18.7 секунды | 0.29 секунды |
| FPM-воркеров | 5 | 40 |
| Bot-capacity | ~50 rps | ~1200 rps |
| OPcache memory | 0 | 512 MB |
Подвох с Coolify
При docker compose up -d --force-recreate контейнер потерял подключение к сети coolify. Это известный баг — Coolify не auto-восстанавливает custom networks при force-recreate.
Симптом: контейнер живой (сам по себе работает), но Traefik его не видит — все маршруты пропали.
Фикс ручной:
docker network connect coolify a107llz9m0spnlfp2tsqpgye-app
docker restart coolify-proxy
Если правишь compose-файл напрямую на Coolify-managed стэке — после
force-recreateвсегда проверь что контейнер на сетиcoolify. Если нет —docker network connect. Иначе Traefik не подцепит роуты.
Что мы делаем теперь
- OPcache + FPM tuning — стандартный baseline для всех новых Bitrix-стэков. Прописан в чек-листе onboarding.
- Алерт на 504 в Uptime Kuma → Telegram-канал команды → SLA 30 минут на response.
- Postmortem-template — каждое срабатывание разбирается в течение 24 часов.
Что почитать дальше
- Bitrix performance tuning checklist (наш гид)
- Coolify network gotchas
- OPcache всегда enable=1 на проде. Это must-have, не optional
- FPM tuning под bot-storm с самого начала, а не после первого 504
- Алертинг на 504 → 30 минут SLA, иначе клиент придёт первым
- Force-recreate Coolify-стэка ломает coolify network — переподключать руками