Beszel — мониторинг для домашней лаборатории, который помещается в один контейнер: веб-интерфейс, история метрик, статусы Docker-контейнеров, SMART и уведомления. Агент ставится на каждую машину, хаб собирает данные и хранит их локально, без облака и внешних сервисов. Для трёх-пяти серверов это проще, чем Prometheus с Grafana и экспортёрами.
Как работает Beszel
Хаб — приложение на Go с веб-интерфейсом и встроенной базой PocketBase. Агент слушает порт 45876 и отдаёт метрики по SSH или через исходящее WebSocket-соединение. Второй вариант удобен за NAT: входящий порт открывать не нужно.
- хаб по умолчанию слушает 8090;
- агент по умолчанию слушает 45876;
- ключ агента — публичная часть SSH-ключа, приватная остаётся на хабе;
- токен связывает агента с хабом через WebSocket;
- данные лежат в
beszel_data, его и нужно бэкапить.
Проект распространяется по лицензии MIT. Это не замена корпоративному мониторингу: здесь нет распределённого хранилища и сложных правил корреляции.
Установка хаба
Проще всего запустить хаб через Docker Compose. Каталог с данными монтируется в контейнер, а APP_URL нужен для правильных ссылок в письмах и уведомлениях.
services:
beszel:
image: henrygd/beszel
container_name: beszel
restart: unless-stopped
environment:
- APP_URL=http://192.168.1.10:8090
ports:
- 8090:8090
volumes:
- ./beszel_data:/beszel_data
mkdir -p /opt/beszel && cd /opt/beszel
docker compose up -d
docker compose logs -f beszel
После запуска откройте http://IP-хаба:8090 и создайте администратора. Если Docker не используется, установочный скрипт кладёт бинарник и unit в systemd:
curl -sL https://get.beszel.dev/hub -o /tmp/install-hub.sh
chmod +x /tmp/install-hub.sh
sudo /tmp/install-hub.sh
systemctl status beszel --no-pager
Скрипт создаёт отдельного пользователя и службу, поэтому хаб переживает перезагрузку. Порт меняется флагом -p, но тогда поправьте APP_URL и firewall.
Подключение агента
В интерфейсе нажмите «Add System» и выберите тип подключения. Хаб покажет публичный ключ и токен; их нужно передать агенту. Для Docker удобно скопировать готовый compose-файл из интерфейса.
services:
beszel-agent:
image: henrygd/beszel-agent
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- ./beszel_agent_data:/var/lib/beszel-agent
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
LISTEN: 45876
KEY: "ssh-ed25519 AAAA... beszel"
HUB_URL: "http://192.168.1.10:8090"
TOKEN: "token-iz-paneli"
network_mode: host нужен, чтобы агент видел сетевые интерфейсы хоста. Если сеть не важна, режим можно убрать и пробросить порт вручную. Для локального агента используйте unix-сокет: localhost между контейнерами не работает.
curl -sL https://get.beszel.dev -o /tmp/install-agent.sh
chmod +x /tmp/install-agent.sh
sudo /tmp/install-agent.sh -k "ssh-ed25519 AAAA..." -p 45876
systemctl status beszel-agent --no-pager
Бинарный агент предпочтительнее, если нужны SMART, температура, GPU и статистика systemd: в rootless-контейнере часть данных недоступна. Секреты храните в файлах через KEY_FILE и TOKEN_FILE.
Что показывает интерфейс
На главной видны загрузка CPU, память, диск, сеть и температура. Внутри системы есть графики за час, день, неделю и месяц, контейнеры с потреблением и логи, а также статусы служб systemd.
- несколько дисков подключаются через
EXTRA_FILESYSTEMS; - датчики фильтруются переменной
SENSORS, интерфейсы —NICS; - контейнеры исключаются шаблоном
EXCLUDE_CONTAINERS; - SMART проверяется по расписанию
SMART_INTERVAL.
Для домашнего сервера полезен набор SERVICE_PATTERNS="docker*,nginx*,beszel*": он добавляет в панель только нужные службы. Проверка обновлений образов включена по умолчанию; в закрытой сети её отключают через DOCKER_IMAGE_CHECK=false.
Алерты и уведомления
Пороговые правила задаются для CPU, памяти, диска, температуры и доступности. Уведомления уходят в почту, Telegram, ntfy, Gotify, Slack и Discord; настройка выполняется в интерфейсе.
Отдельно включите heartbeat: хаб раз в минуту отправляет запрос на внешний URL. Если пинги прекратились, внешний сервис сообщит о проблеме и защитит от молчаливой смерти мониторинга.
HEARTBEAT_URL: "https://hc-ping.com/vash-uuid"
HEARTBEAT_INTERVAL: "60"
MFA_OTP: "true"
MFA_OTP включает одноразовый код на почту, но только после настройки SMTP. Для дома достаточно длинного пароля и локального доступа к панели.
Доступ снаружи и безопасность
Не публикуйте 8090 напрямую. Поставьте обратный прокси с TLS и ограничьте вход по сети. Caddy справится с сертификатом автоматически:
beszel.example.com {
reverse_proxy 127.0.0.1:8090
}
Прокси должен пропускать SSE и не сжимать text/event-stream, иначе графики перестанут обновляться. Для агентов в SSH-режиме закройте 45876 от всех, кроме хаба:
sudo ufw allow from 192.168.1.10 to any port 45876 proto tcp
sudo ufw deny 45876/tcp
sudo ufw reload
sudo ufw status numbered
Если агенты подключаются через WebSocket, входящий порт им не нужен: достаточно исходящего доступа к хабу. Ключи и токены храните в файлах с правами 600.
Обслуживание и резервные копии
История метрик и настройки лежат в beszel_data. В интерфейсе есть резервное копирование на диск и в S3-совместимое хранилище; для небольшой установки достаточно остановить хаб и скопировать каталог.
docker compose stop beszel
tar czf /var/backups/beszel-$(date +%F).tar.gz beszel_data
docker compose start beszel
docker compose pull && docker compose up -d
Обновляйте хаб и агентов вместе: версии должны быть совместимы, иначе старый агент не подключится.
Диагностика: агент не подключается
Сначала определите направление соединения. В SSH-режиме хаб сам идёт на порт агента, в WebSocket-режиме агент идёт на хаб. Проверка:
nc -vz 192.168.1.20 45876
curl -I http://192.168.1.10:8090
docker logs --tail 50 beszel-agent
journalctl -u beszel-agent -n 50 --no-pager
ss -lntp | grep 45876
- порт закрыт — проверьте ufw/nftables и адрес привязки;
- ключ не совпадает — скопируйте его из карточки системы заново;
- WebSocket не проходит — проверьте прокси и заголовки
Upgrade; - контейнеры без статистики — смонтирован ли
docker.sockи есть ли права.
Итог
Beszel закрывает типовую задачу домашней лаборатории: увидеть, что все машины живы, диск не заполнен, контейнеры работают, а температура в норме. Он не требует облака, сложной базы и десятка экспортёров, а установка занимает меньше десяти минут.
Начните с хаба и одного агента, добавьте уведомления и heartbeat, затем спрячьте панель за обратным прокси и включите MFA. Для пяти серверов этого достаточно; когда появятся сложные правила, станет видно, нужен ли переход на Prometheus.