Мониторинг без космолёта: узнаём о сбое раньше пользователя
Для первого проекта не нужен огромный стек наблюдаемости. Нужны четыре сигнала: сервер жив, диск не заполнен, контейнер работает, приложение отвечает снаружи.
Три уровня проверки
Инфраструктура — CPU, память и диск. Процесс — состояние контейнера и его перезапуски. Приложение — реальный HTTPS‑ответ. Если проверять только один уровень, можно пропустить проблему на другом.
1. Смотрим на сервер вручную
free -h
df -h
htop
sudo systemctl --failed
В uptime три числа load average показывают среднюю очередь задач за 1, 5 и 15 минут. Для одноядерного VPS постоянное значение заметно выше 1 требует внимания. В free -h ориентируйтесь на available, а не просто free: Linux использует свободную память под кэш.
Диск лучше не доводить выше 80–85%. При 100% перестают записываться логи и база, а приложение начинает вести себя странно.
2. Проверяем контейнеры
docker compose ps
docker stats --no-stream
docker compose logs --tail=100
Состояние Up — процесс работает. Restarting означает цикл падений. Колонка STATUS с healthcheck надёжнее простого «процесс существует».
3. Добавляем endpoint здоровья
Простейший endpoint FastAPI:
async def health():
return {"status": "ok"}
В Compose:
test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
Если в образе нет curl, установите его или используйте проверку на Python. После изменения пересоберите контейнер и смотрите docker compose ps.
4. Проверяем снаружи
Внешний uptime‑сервис раз в несколько минут открывает https://example.ru/health. Настройте:
- ожидаемый HTTP‑код 200;
- проверку текста
ok; - уведомление в Telegram или почту;
- повторную проверку перед алертом, чтобы отсечь краткий сетевой шум.
Это важнее локального healthcheck: внешний монитор замечает проблемы DNS, сертификата, Nginx и самого VPS.
5. Читаем логи, а не гадаем
journalctl -p err -S today
journalctl -u nginx --since "1 hour ago"
sudo tail -n 100 /var/log/nginx/error.log
Читайте от симптома ко времени: когда пришёл алерт, какой код вернул Nginx, что писал контейнер за минуту до этого. Не складывайте в логи токены, пароли, полные сообщения пользователей и другие персональные данные.
6. Не даём логам съесть диск
В Compose задайте ротацию:
driver: json-file
options:
max-size: "10m"
max-file: "3"
После изменения контейнер нужно пересоздать. Проверьте занятое Docker место:
sudo du -xh /var/lib/docker | sort -h | tail
7. Что делать при алерте
- Подтвердить проблему через браузер или
curl. - Проверить место, память и load average.
- Посмотреть состояние контейнера и последние логи.
- Если причина понятна — исправить минимальным действием.
- Если непонятна — сохранить логи, откатить последний релиз.
- После восстановления записать причину и профилактику.
Безопасная короткая диагностика:
uptime
free -h
df -h
docker compose ps
docker compose logs --tail=100
8. Регламент маленького проекта
- постоянно: внешний uptime и уведомления;
- раз в неделю: диск, ошибки, доступные security‑обновления;
- раз в месяц: тест восстановления бэкапа;
- перед релизом: бэкап и понятный план отката;
- после сбоя: короткий разбор без поиска виноватых.
Маршрут завершён
У вас есть защищённый VPS, контейнерный запуск, HTTPS, внешние копии и базовая наблюдаемость. Сохраните каталог RateHost как чек‑лист следующего проекта.