Привет, Хабр!

В своих предыдущих статьях (раз, два, три) я рассказывал о зарождении идеи и первых шагах разработки Telegram-бота для управления серверами. То, что начиналось как простенький Python-скрипт для проверки uptime и перезагрузки парочки личных VPS, за последние месяцы обросло «мясом» и превратилось во взрослую экосистему с паттерном Agent-Server, своим WebUI, WAF и PWA.

Сегодня я хочу поделиться опытом, который я получил в процессе масштабного рефакторинга (от версии 1.13.0 до актуальной 1.21.x), рассказать о граблях, на которые я наступил при работе с памятью и сетью, и сравнить свой продукт с тем, что уже есть на рынке.

Сразу оговорюсь: хоть я и числюсь единственным разработчиком, проект создается не в вакууме. Во-первых, для ускорения развития продукта я активно использую инструменты ИИ. Сейчас это модно называть «вайбкодингом» (vibe-coding), но в моем случае это осознанный вайбкодинг. Я не перекладываю на нейросети проект целиком, а использую их для автоматизации рутины, сохраняя при этом полное понимание каждой строчки кода, его структуры и заложенной архитектуры. Во-вторых, у меня есть боевой товарищ — друг-тестировщик, который использует панель для своих повседневных задач, нещадно ломает новые фичи на проде, репортит баги и вносит огромный вклад в развитие. Именно благодаря такой живой обкатке инструмент получается действительно юзабельным. И, забегая вперед, вы тоже можете присоединиться к этому процессу!


Архитектурные боли и «подкапотная» механика

Когда проект выходит за рамки «бота для одного человека» и начинает управлять десятками удаленных нод (клиентов), старые архитектурные решения начинают трещать по швам. Вот с чем я столкнулся и как это решал.

1. Смерть JSON-баз и переход на SQLite с шифрованием

В ранних версиях вся конфигурация и список серверов хранились в обычных .json файлах. Это было удобно для дебага, но как только бот стал асинхронно опрашивать ноды, начались проблемы с конкурентным доступом (Race Conditions) и риском повреждения данных при внезапном рестарте.

Решение: В версиях 1.16 – 1.21 я полностью перевел логику на aiosqlite. Теперь метрики, история и список нод живут в транзакционной базе. Но конфигурации — это чувствительная зона. Поэтому я внедрил шифрование Fernet (AES). Все конфиги на диске теперь зашифрованы, а пароли веб-панели хешируются через Argon2.

2. Проблема OOM (Out of Memory) и потоковое чтение логов

Чтение системных логов (например, journalctl или логов сервисов) раньше делалось «в лоб» — вычитывался весь файл и отправлялся пользователю. Мой друг-тестировщик как раз гонял бота на очень слабых виртуалках с 512 МБ RAM, и это стабильно приводило к OOM Kill процесса.

Решение: Я перешел на использование кольцевых буферов (collections.deque) и потоковое чтение. Теперь логи стримятся через Server-Sent Events (SSE) в веб-интерфейс, а в самом боте в памяти держится только жестко лимитированный хвост лога. Дополнительно я внедрил регулярную очистку (garbage collection). Потребление RAM агента упало и зафиксировалось на отметке ~100 МБ.

3. Отказ от Polling в пользу SSE и WebSockets

Классический подход к веб-мониторингу ресурсов — отправлять AJAX-запрос каждую секунду. При 10-20 нодах это генерировало бессмысленный паразитный трафик и грузило CPU сервера.

Решение: Я полностью перевел WebUI на Server-Sent Events (SSE). Бот сам пушит обновления (CPU, RAM, статусы сервисов) в браузер только тогда, когда они реально меняются.


Что нового появилось в версиях 1.13.0 — 1.21.1?

Проект обзавелся фичами, характерными для коммерческих панелей. Кстати, у бота теперь есть свой сайт-визитка — сайт, где собрана основная информация:

  • Полноценный Web Terminal (v1.21.0): Защищенная консоль прямо в браузере, работающая поверх WebSocket. Я заморочился с адаптацией под мобильные устройства: обработка 100dvh для iOS/Android и интерактивная клавиатура в стиле Termius.

  • Reverse Heartbeat (v1.20.0): Механизм обратного опроса. Теперь не главный бот «пингует» ноды, а сами ноды регулярно отчитываются о своем состоянии главному серверу. Это сильно упростило работу через NAT и фаерволы.

  • Умный менеджер бэкапов (v1.20.0): Прямо из Telegram можно делать бэкапы конфигов, логов и трафика. Добавлена ротация (хранятся последние 5 копий) и настраиваемые таймеры автобэкапа.

  • Менеджер сервисов (v1.18.0): Управление systemd сервисами (Start/Stop/Restart) через WebUI с живым статусом и потоковыми логами.

  • Встроенный WAF и безопасность (v1.18.0): Web Application Firewall защищает веб-панель от SQLi, XSS и Path Traversal. Встроен Rate Limiter (от DDoS) и защита от брутфорса (бан после 5 попыток).

  • Smart Speedtest (v1.19.0): Переработана логика замеров скорости. Для RU-сегмента бот автоматически использует iperf3 со списком локальных серверов, а для остального мира — классический Speedtest.


Сравнение с рынком: где находится проект?

Когда делаешь свой инструмент, важно понимать, чем он отличается от аналогов. Мой проект балансирует на стыке нескольких классов ПО.

vs. Тяжелые панели (ISPmanager, Pterodactyl, Plesk)

  • Их сильная сторона: Огромный функционал для предоставления shared-хостинга, биллинг, жесткая изоляция пользователей.

  • Сильная сторона проекта: Легковесность. Мне не нужны Apache, PHP или MySQL. Бот разворачивается одним скриптом deploy.sh в Docker или Systemd за минуту. Инструмент создан не для продажи хостинга, а для удобного администрирования своей личной инфраструктуры.

vs. Классический мониторинг (Zabbix, Prometheus + Grafana)

  • Их сильная сторона: Глубочайшая аналитика, построение сложных зависимостей и графиков за годы.

  • Сильная сторона проекта: Низкий порог входа. Настроить Prometheus + Grafana с алертами в Telegram — это вечер работы. Поставить этого бота — пара минут. Плюс, это не просто мониторинг, но и управление (перезагрузка, терминал, управление сервисами).

vs. Клиентские приложения (Termius, ServerBox)

  • Их сильная сторона: Красивые нативные клиенты под все платформы.

  • Сильная сторона проекта: Не нужно устанавливать отдельное приложение на телефон. Уведомления приходят в родной Telegram (который всегда под рукой), а дашборд открывается через PWA-ссылку. К тому же, проект Open-Source и Self-Hosted: ваши данные не улетают на чужие облачные сервера.

Слабые стороны

Буду честен, ограничения тоже есть:

  1. Масштабируемость SQLite: Если у вас 1000+ нод с ежесекундным обновлением метрик, SQLite станет бутылочным горлышком (локи базы). Для сурового энтерпрайза нужен переход на PostgreSQL.

  2. Зависимость от Telegram: Если сервера мессенджера "ложатся", вы теряете канал алертинга (хотя WebUI остается доступен по IP-адресу).


Призыв к комьюнити

Проект полностью открыт, распространяется под лицензией GPL-3.0 и живет на энтузиазме. Как я уже говорил, мой друг активно пользуется панелью и помогает находить слабые места. И вы тоже можете это делать! Если вы сисадмин, DevOps-инженер или просто энтузиаст, который держит личные пет-проекты для друзей на парочке VPS — этот инструмент написан для вас. Заглядывайте на сайт бота!

Что можно сделать прямо сейчас:

  1. Потестируйте скрипт установки: Выполните bash <(wget -qO- https://raw.githubusercontent.com/jatixs/tgbotvpscp/main/deploy.sh) на тестовой виртуалке.

  2. Ломайте и багрепортьте: Попробуйте положить агента, проверьте WAF на прочность. Пишите Issue на GitHub, как это делает мой друг-тестировщик!

  3. Контрибьютьте: Проект написан на понятном Python (Aiogram 3 + Aiohttp). Если вам не хватает модуля — в репозитории есть инструкция custom_module.md по созданию собственных плагинов. Я рад любым Pull Requests!

⭐ Звезды на GitHub очень мотивируют пилить обновления по ночам.

Делитесь в комментариях: чем вы мониторите свой зоопарк серверов и какие фичи хотели бы видеть в подобных легковесных панелях?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Развиваем?
75%Да, я в деле!3
25%Очередной мусор1
Проголосовали 4 пользователя. Воздержавшихся нет.