Привет, Хабр!
В своих предыдущих статьях (раз, два, три) я рассказывал о зарождении идеи и первых шагах разработки 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: ваши данные не улетают на чужие облачные сервера.
Слабые стороны
Буду честен, ограничения тоже есть:
Масштабируемость SQLite: Если у вас 1000+ нод с ежесекундным обновлением метрик, SQLite станет бутылочным горлышком (локи базы). Для сурового энтерпрайза нужен переход на PostgreSQL.
Зависимость от Telegram: Если сервера мессенджера "ложатся", вы теряете канал алертинга (хотя WebUI остается доступен по IP-адресу).
Призыв к комьюнити
Проект полностью открыт, распространяется под лицензией GPL-3.0 и живет на энтузиазме. Как я уже говорил, мой друг активно пользуется панелью и помогает находить слабые места. И вы тоже можете это делать! Если вы сисадмин, DevOps-инженер или просто энтузиаст, который держит личные пет-проекты для друзей на парочке VPS — этот инструмент написан для вас. Заглядывайте на сайт бота!
Что можно сделать прямо сейчас:
Потестируйте скрипт установки: Выполните
bash <(wget -qO-https://raw.githubusercontent.com/jatixs/tgbotvpscp/main/deploy.sh)на тестовой виртуалке.Ломайте и багрепортьте: Попробуйте положить агента, проверьте WAF на прочность. Пишите Issue на GitHub, как это делает мой друг-тестировщик!
Контрибьютьте: Проект написан на понятном Python (Aiogram 3 + Aiohttp). Если вам не хватает модуля — в репозитории есть инструкция
custom_module.mdпо созданию собственных плагинов. Я рад любым Pull Requests!
⭐ Звезды на GitHub очень мотивируют пилить обновления по ночам.
Делитесь в комментариях: чем вы мониторите свой зоопарк серверов и какие фичи хотели бы видеть в подобных легковесных панелях?
