@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 15 hours ago
monitor feat: deploy.sh — one-command agent rollout over SSH (+ README guide) 16 hours ago
panel feat: MCP server at /mcp — AI agents read server state from the panel 15 hours ago
.dockerignore feat: stage 3 — Vue web UI (dashboard, server page, charts) + docker build 16 hours ago
.gitignore feat: stage 3 — Vue web UI (dashboard, server page, charts) + docker build 16 hours ago
README.md feat: MCP server at /mcp — AI agents read server state from the panel 15 hours ago
docker-compose.yml feat: stage 3 — Vue web UI (dashboard, server page, charts) + docker build 16 hours ago
README.md

GHard Monitor

Gnexus Hardware Monitor — сбор мониторинга всех серверов в одном месте.

┌───────────────┐   POST /api/v1/ingest   ┌────────────────────┐
│ hard-monitor  │ ─────────────────────► │  hard-panel        │
│ (агент,       │   метрики + ключ       │  FastAPI + SQLite  │
│  stateless)   │                        │  + Vue UI          │
└───────────────┘                        └────────────────────┘
  • panel/ — панель: приём метрик, SQLite, ивенты, алерты, веб-интерфейс (Vue 3 + gnexus-ui-kit + chart.js)
  • monitor/ — агент на серверах: psutil-сбор фактов, POST на панель. Агент stateless, вся логика (пороги, ивенты, скорость сети по дельте счётчиков) — на панели.

Стек

Часть Технологии
panel backend Python 3.12, FastAPI, aiosqlite (SQLite, WAL)
panel frontend Vue 3, gnexus-ui-kit, chart.js
monitor Python 3.8+ (psutil, requests), systemd
Деплой Docker / docker-compose

Разворачивание panel

Нужен сервер с docker и docker compose. SQLite живёт в volume — отдельной БД не надо.

git clone https://git.gnexus.space/git/root/hard-panel.git
cd hard-panel

1. Конфиг — корень репо, рядом с docker-compose.yml:

cp panel/backend/.env.example .env

Отредактируй .env:

# порт, на котором панель слушает снаружи (по умолчанию 8000)
GHARD_PANEL_PORT=8000

GHARD_ADMIN_TOKEN — опционален: веб-интерфейс работает без логина. Если задать токен, API панели (создание серверов, метрики) закроется Bearer-токеном — удобно, когда панель торчит в интернет, а UI тебе не нужен. Единственная настоящая авторизация в системе — ключи агентов (ghm_...).

2. Запуск:

docker compose up -d --build

Проверка: curl http://localhost:8000/api/v1/health{"status":"ok"}. OpenAPI-документация: http://localhost:8000/docs.

3. Reverse proxy (рекомендуется) — агенты будут слать метрики из интернета, поэтому панель стоит закрыть TLS-ом. Пример Caddy:

panel.example.com {
    reverse_proxy 127.0.0.1:8000
}

Caddy сам выпустит сертификат. Для nginx: proxy_pass http://127.0.0.1:8000; и обычный certbot. Заголовок X-Forwarded-For панель учитывает — в карточке сервера будет виден реальный IP агента.

Добавление сервера и установка агента

Проще всего — кнопка «Добавить сервер» в веб-интерфейсе. Через API то же самое:

curl -X POST https://panel.example.com/api/v1/servers \
    -H "Content-Type: application/json" \
    -d '{"name": "web-01"}'

Ответ — plaintext-ключ, показывается один раз, сохрани сразу:

{"id": 1, "name": "web-01", "key": "ghm_KyfA9jheG9OSZxFlfFmdx8yFpO3tZAcO"}

Дальше на целевом сервере (python3 + pip):

curl -fsSL https://git.gnexus.space/root/hard-panel/raw/branch/master/monitor/install.sh | \
    sudo bash -s -- https://panel.example.com ghm_KyfA9jheG9OSZ... 30

Скрипт поставит всё в /opt/hard-monitor (venv + psutil + requests), запишет .env с правами 600, установит systemd-юнит hard-monitor и запустит. Повторный запуск — обновление агента.

Логи и управление:

journalctl -u hard-monitor -f      # смотреть логи
systemctl restart hard-monitor     # рестарт

Проверка на панели — сервер должен получить status: "online":

curl -s https://panel.example.com/api/v1/servers

Массовое развёртывание агентов (в том числе ИИ-агентом)

monitor/deploy.sh делает весь цикл сам: создаёт сервер на панели → заходит по SSH → ставит агента → ждёт первый пакет. Одна команда на любое число хостов:

cd monitor
./deploy.sh --panel https://panel.example.com user@web-01 user@db-01 user@cache-01

Опции:

Опция Что делает
--panel URL адрес панели (обязательно)
--token TOKEN GHARD_ADMIN_TOKEN — нужен, только если токен на панели задан
--interval N интервал агента в секундах (по умолчанию 30)
--recreate удалить существующую запись сервера на панели и создать заново (новый ключ); без него ключ переиспользуется из /opt/hard-monitor/.env на хосте
--git-install ставить curl-ом из репозитория; по умолчанию файлы агента заливаются scp с локальной машины

Требования к хостам: SSH-доступ по ключу, python3, sudo без пароля. Повторный запуск на уже развёрнутом хосте — обновление агента (запись на панели и ключ сохраняются).

Развёртывание ИИ-агентом (Claude Code и т.п.)

Скрипт специально сделан неинтерактивным и идемпотентным, чтобы его мог запустить ИИ-агент с SSH-доступом к машинам. Промт для агента:

Разверни hard-monitor на моих серверах. Панель: https://panel.example.com
1. Склонируй https://git.gnexus.space/git/root/hard-panel.git (нужна папка monitor/)
2. Запусти: cd monitor && ./deploy.sh --panel https://panel.example.com user@host1 user@host2 ...
3. Если какой-то хост упал с ошибкой — разберись (ssh, journalctl -u hard-monitor),
   почини и перезапусти deploy.sh только для этого хоста
4. Проверь, что все серверы online: curl -s https://panel.example.com/api/v1/servers
   (у каждого status: "online")

Агенту не нужен доступ к UI панели: серверы создаются через API, ключи никогда не показываются человеку и не сохраняются — install.sh сразу кладёт их в /opt/hard-monitor/.env (права 600).

Обновление

Panel — на сервере с панелью:

cd hard-panel
git pull
docker compose up -d --build

Агент — на каждом сервере (нужны свежие hard_monitor.py / hard-monitor.service в текущем каталоге — склонируй репо):

git clone https://git.gnexus.space/git/root/hard-panel.git && cd hard-panel/monitor
sudo ./install.sh   # с теми же PANEL_URL/SERVER_KEY — перезапишет файлы и рестартанёт

Или вручную: скопируй hard_monitor.py в /opt/hard-monitor/ и systemctl restart hard-monitor. Конфиг .env не трогается.

Бэкапы

Вся панель — один файл SQLite в volume panel-data. Полный бэкап:

docker compose exec panel python -c \
    "import sqlite3; sqlite3.connect('/data/hard-panel.db').backup(sqlite3.connect('/data/backup.db'))"
docker compose cp panel:/data/backup.db ./hard-panel-backup.db

(или просто остановить и скопировать volume). Ключи серверов в БД — хэши, восстановить plaintext из бэкапа нельзя: потерянный ключ — пересоздай сервер.

Конфигурация panel (env)

Переменная По умолчанию Описание
GHARD_ADMIN_TOKEN (пусто) опциональный Bearer-токен API; веб-интерфейс работает без логина
GHARD_DATABASE_PATH /data/hard-panel.db путь к SQLite
GHARD_PANEL_PORT 8000 host-порт (docker-compose)
GHARD_OFFLINE_MULTIPLIER 3 offline = нет пакетов дольше N × interval

API (кратко)

  • POST /api/v1/servers — создать сервер, получить ключ агента (один раз)
  • POST /api/v1/ingest — пакет метрик агента, заголовок X-Server-Key
  • GET /api/v1/servers — сводка для дашборда
  • GET /api/v1/servers/{id} — карточка + последняя точка
  • GET /api/v1/servers/{id}/metrics?since=…&until=… — история для графиков
  • PATCH /api/v1/servers/{id} — имя / заметка
  • DELETE /api/v1/servers/{id} — удалить сервер (с каскадом метрик)

MCP для ИИ-агентов

Панель сама является MCP-сервером (streamable HTTP, по умолчанию /mcp) — любой ИИ-агент подключается по URL панели и читает состояние серверов.

Инструменты:

Tool Что отдаёт
panel_overview все серверы одной сводкой: статус, CPU/RAM/диск, сеть, последний пакет
server_details полное состояние сервера: метрики, диски, процессы, docker, заметка
server_history история метрик за N часов, прореженная до N точек

Подключение (Claude Code):

claude mcp add --transport http ghard https://panel.example.com/mcp

Для любого другого MCP-клиента — тот же URL, транспорт streamable HTTP. После подключения агент может отвечать на вопросы «как мои серверы?», «что тормозит на web-01?», «растёт ли диск на db-01 за сутки?» без доступа к веб-интерфейсу.

Заметка про токен: /mcp сейчас открыт так же, как REST API при пустом GHARD_ADMIN_TOKEN. Если панель торчит в интернет и ты задаёшь токен — закрой /mcp на reverse proxy или оставь доступ только из доверенной сети, иначе любой сможет читать метрики.

Статус

  • Этап 1 — скелет: FastAPI, SQLite-схема, ingest, servers API, docker
  • Этап 2 — hard-monitor агент + install.sh + systemd
  • Этап 3 — веб-интерфейс (Vue + ui-kit + chart.js)
  • Этап 4 — ивенты + алерты (Telegram, webhook)
  • Этап 5 — downsample истории (7 дней), финальный деплой