Настройка watchdog для Telegram-бота

Короткий ответ
Автоматический перезапуск зависшего aiogram 3-бота в Docker Compose обеспечивается путем добавления в код heartbeat, настройки healthcheck в compose.yaml и подключения сервиса autoheal.
  1. В коде бота добавьте coroutine heartbeat, которая каждую 10 cек делает Path('/tmp/bot.heartbeat').touch(), оберните await dp.start_polling(bot) в try/finally, где в finally отменяете задачу heartbeat и ждёте её сбора, а рядом с compose.yaml создайте healthcheck.py с проверкой mtime('/tmp/bot.heartbeat') < 90 сек.
  2. В compose.yaml для сервиса bot добавьте restart: unless-stopped, метку watchdog-tg: “true”, healthcheck с test: ["CMD","python","/opt/healthcheck.py"] (interval:30s,timeout:5s,retries:3,start_period:60s) и монтирование ./healthcheck.py:/opt/healthcheck.py, а на том же уровне опишите сервис autoheal с образом willfarrell/autoheal, volume /var/run/docker.sock:/var/run/docker.sock и переменными AUTOHEAL_CONTAINER_LABEL=watchdog-tg, AUTOHEAL_INTERVAL=10, после чего выполнить docker compose up -d --build bot autoheal.

Настройка 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.

При обнаружении зависания контейнер будет автоматически перезапущен согласно настроенной схеме контроля.

Не нашли ответа на свой вопрос?

Заказать звонок

Оставьте свои данные для того, чтобы специалист с вами связался.