diff --git a/README.md b/README.md index 2297e97..15e0d52 100644 --- a/README.md +++ b/README.md @@ -22,30 +22,160 @@ |---|---| | panel backend | Python 3.12, FastAPI, aiosqlite (SQLite, WAL) | | panel frontend | Vue 3, gnexus-ui-kit, chart.js | -| monitor | Python 3 (psutil, requests), systemd | +| monitor | Python 3.8+ (psutil, requests), systemd | | Деплой | Docker / docker-compose | -## Быстрый старт (panel) +## Разворачивание panel + +Нужен сервер с docker и docker compose. SQLite живёт в volume — отдельной +БД не надо. ```bash -cp panel/backend/.env.example .env # задай GHARD_ADMIN_TOKEN +git clone https://git.gnexus.space/git/root/hard-panel.git +cd hard-panel +``` + +**1. Конфиг** — корень репо, рядом с docker-compose.yml: + +```bash +cp panel/backend/.env.example .env +``` + +Отредактируй `.env`: + +```ini +# токен админ-доступа к API панели — сгенерируй свой +GHARD_ADMIN_TOKEN= + +# порт, на котором панель слушает снаружи (по умолчанию 8000) +GHARD_PANEL_PORT=8000 +``` + +`GHARD_ADMIN_TOKEN` — единственный секрет панели; с ним можно +создавать/удалять серверы и читать метрики, береги его. + +**2. Запуск:** + +```bash docker compose up -d --build ``` -API: `http://localhost:8000/docs` (OpenAPI) +Проверка: `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 агента. + +## Добавление сервера и установка агента + +Пока нет веб-интерфейса (этап 3), сервер создаётся через API: + +```bash +curl -X POST https://panel.example.com/api/v1/servers \ + -H "Authorization: Bearer $GHARD_ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name": "web-01"}' +``` + +Ответ — **plaintext-ключ, показывается один раз**, сохрани сразу: + +```json +{"id": 1, "name": "web-01", "key": "ghm_KyfA9jheG9OSZxFlfFmdx8yFpO3tZAcO"} +``` + +Дальше на целевом сервере (python3 + pip): + +```bash +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` и +запустит. Повторный запуск — обновление агента. + +Логи и управление: + +```bash +journalctl -u hard-monitor -f # смотреть логи +systemctl restart hard-monitor # рестарт +``` + +Проверка на панели — сервер должен получить `status: "online"`: + +```bash +curl -s https://panel.example.com/api/v1/servers \ + -H "Authorization: Bearer $GHARD_ADMIN_TOKEN" +``` + +## Обновление + +**Panel** — на сервере с панелью: + +```bash +cd hard-panel +git pull +docker compose up -d --build +``` + +**Агент** — на каждом сервере (нужны свежие `hard_monitor.py` / +`hard-monitor.service` в текущем каталоге — склонируй репо): + +```bash +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`. Полный бэкап: + +```bash +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` | `change-me` | токен админ-доступа к 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/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}` — удалить сервер (с каскадом метрик) ## Статус - [x] Этап 1 — скелет: FastAPI, SQLite-схема, ingest, servers API, docker -- [ ] Этап 2 — hard-monitor агент + install.sh +- [x] Этап 2 — hard-monitor агент + install.sh + systemd - [ ] Этап 3 — веб-интерфейс (Vue + ui-kit + chart.js) - [ ] Этап 4 — ивенты + алерты (Telegram, webhook) - [ ] Этап 5 — downsample истории (7 дней), финальный деплой \ No newline at end of file