Настройка watchdog для Python 3.13, aiogram 3 и Docker Compose на Linux-сервере. Схема позволяет восстанавливать процесс после завершения и после блокировки основного цикла asyncio.
Используемые инструменты
Python 3.13
Язык для логики бота и проверки watchdog.
Docker Compose
Инструмент настройки и запуска контейнеров бота и watchdog через compose.yaml.
aiogram 3
Библиотека Python для работы с Telegram Bot API.
1. Подготовка
Нужны Docker Engine, команда docker compose, доступ к проекту и сокету:
/var/run/docker.sock
Все команды ниже выполняйте в каталоге с compose.yaml.
Сохраните текущую конфигурацию перед изменениями.
Важно: Обычный restart перезапускает завершившийся контейнер. Healthcheck только выставляет статус unhealthy. Отдельный сервис autoheal отслеживает этот статус и перезапускает бот.
2. Проверка зависания бота
В модуль запуска бота добавьте heartbeat — обновление файла каждые 10 секунд в том же цикле asyncio, где работает бот.
import asyncio
from pathlib import Path
async def heartbeat():
while True:
Path('/tmp/bot.heartbeat').touch()
await asyncio.sleep(10)
Запуск heartbeat для long polling
В существующей async-функции main() замените вызов:
await dp.start_polling(bot)
следующим блоком:
heartbeat_task = asyncio.create_task(heartbeat())
try:
await dp.start_polling(bot)
finally:
heartbeat_task.cancel()
await asyncio.gather(
heartbeat_task,
return_exceptions=True
)
Важно: dp и bot — уже созданные Dispatcher и Bot. Регистрацию роутеров сохраните.
При webhook запускайте и завершайте задачу в startup/shutdown того же веб-приложения.
Не выносите heartbeat в отдельный процесс или поток.
Проверка обнаруживает блокировку цикла asyncio, но не отдельную зависшую задачу.
Для контроля polling дополнительно проверяйте время последнего успешного getUpdates, включая пустой ответ.
Отсутствие сообщений не является сбоем.
Создание healthcheck.py
Рядом с compose.yaml создайте файл:
healthcheck.py
Проверка успешна, если файл обновлялся менее 90 секунд назад.
import os
import sys
import time
try:
age = time.time() - os.path.getmtime(
'/tmp/bot.heartbeat'
)
sys.exit(
0 if 0 <= age < 90 else 1
)
except OSError:
sys.exit(1)
3. Настройка Docker Compose
В существующий сервис бота добавьте параметры ниже, сохранив его image/build, command, переменные, сети и тома.
Здесь bot — имя сервиса. Если у вас используется другое имя, замените его в командах.
Добавьте autoheal на том же уровне.
services:
bot:
# Сохраните здесь существующие image/build и настройки.
restart: unless-stopped
labels:
watchdog-tg: "true"
volumes:
- ./healthcheck.py:/opt/healthcheck.py:ro
healthcheck:
test:
["CMD", "python", "/opt/healthcheck.py"]
interval: 30s
timeout: 5s
retries: 3
start_period: 60s
autoheal:
image: willfarrell/autoheal:latest
restart: unless-stopped
network_mode: none
environment:
AUTOHEAL_CONTAINER_LABEL: watchdog-tg
AUTOHEAL_INTERVAL: "10"
AUTOHEAL_DEFAULT_STOP_TIMEOUT: "10"
AUTOHEAL_ONLY_MONITOR_RUNNING: "true"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Важно: Это фрагмент для объединения с текущим compose.yaml. Не создавайте второй ключ volumes или labels: добавьте строки в существующие списки.
Метку watchdog-tg ставьте только нужному боту.
Доступ к Docker socket даёт autoheal широкие права на сервере. Используйте доверенный образ, после проверки закрепите его digest вместо latest.
Параметры проверки
| Параметр | Значение |
|---|---|
| Порог heartbeat | 90 секунд |
| Период проверки healthcheck | 30 секунд |
| Количество ошибок до перезапуска | 3 ошибки подряд |
| Период запуска | 60 секунд |
На старте ошибки не учитываются первые 60 секунд, пока проверка ещё не была успешной.
Обнаружение блокировки обычно занимает около 2–3 минут плюс время остановки и запуска бота.
AUTOHEAL_INTERVAL — частота опроса, а не отдельная пауза между перезапусками.
Лимита числа перезапусков в этой схеме нет.
4. Запуск и контроль
Пересоберите образ бота с добавленным heartbeat.
Если используется готовый image из реестра, сначала соберите и опубликуйте обновлённый образ, затем укажите его тег.
docker compose config --quiet
docker compose up -d --build bot autoheal
docker compose ps
docker compose logs --tail=50 bot autoheal
Дождитесь статуса healthy у bot и проверьте ответ на известную команду в Telegram. Статус running без healthy ещё не подтверждает работу проверки.
5. Тест восстановления
Проводите тест на тестовом экземпляре или в согласованное время: бот будет перезапущен.
Временно замените только строку healthcheck.test у bot:
test:
["CMD", "python", "-c", "raise SystemExit(1)"]
Примените изменения командой:
docker compose up -d bot
Через несколько минут в логах autoheal должна появиться запись о перезапуске unhealthy-контейнера.
Важно: Сразу верните исходную строку test и снова выполните:
docker compose up -d bot
Иначе перезапуски продолжатся.
Убедитесь, что bot стал healthy и отвечает в Telegram.
Проверка тестирует цепочку:
ошибка проверки → перезапуск
Корректность heartbeat проверяйте отдельно при интеграции в код.
Настройка завершена
После выполнения настройки Telegram-бот будет автоматически контролироваться через heartbeat, healthcheck и autoheal.
При обнаружении зависания контейнер будет автоматически перезапущен согласно настроенной схеме контроля.