Files
Proxmox-VPS-Panel/README.md
T
2026-07-24 22:08:51 +03:00

181 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Proxmox VPS Panel
Self-hosted панель для мульти-тенантного управления VPS (VM и LXC) на вашем
Proxmox VE через API. Backend — FastAPI (Python), frontend — React (Vite), хранилище — Postgres.
Клиенты регистрируются, выбирают шаблон и разворачивают себе VM или LXC-контейнер одной кнопкой;
дальше могут запускать/останавливать/перезагружать/удалять сервер и открывать веб-консоль.
Первый зарегистрированный пользователь автоматически становится администратором и управляет
шаблонами и списком пользователей.
## Возможности
- Регистрация/логин (JWT), роли admin / client
- Шаблоны VPS: админ создаёт тарифы, привязанные к VM-шаблону (клонирование) или CT-шаблону LXC
- Клиент создаёт инстанс из шаблона — панель сама берёт свободный VMID и вызывает Proxmox API
- Действия: start / stop / shutdown / reboot / delete
- Веб-консоль через noVNC (websocket-прокси на backend, noVNC устанавливается из npm)
- Проверка владельца во всех эндпоинтах — клиент не может управлять чужими VM
- Всё через docker-compose, разворачивается как Custom App в TrueNAS SCALE
- Healthcheck-эндпоинты (`/health`, `/health/ready`) и Docker-healthcheck у всех сервисов
- Backend работает от непривилегированного пользователя (non-root)
## Чего нет (сознательно, чтобы не раздувать первую версию)
- Поддержки нескольких Proxmox-нод/кластеров одновременно (сейчас один `PVE_NODE` в конфиге)
- Биллинга и лимитов по ресурсам на пользователя
- Очереди задач (Celery/Redis) — создание VPS идёт в фоне через `BackgroundTasks` FastAPI,
для нескольких одновременных заявок этого достаточно, для десятков в секунду — уже нет
- Управления сетью/IP-пулами (LXC получает адрес по DHCP, для VM выдаётся из клонированного шаблона)
- Alembic-миграций (сейчас `create_all()` — для прода рекомендуется добавить)
## 1. Подготовка Proxmox
### API-токен
Datacenter → Permissions → API Tokens → добавить токен для пользователя (например `root@pam`,
в проде лучше завести отдельного пользователя с ролью `PVEVMAdmin`/кастомной ролью и без
"Privilege Separation", если хотите, чтобы токен имел те же права, что и юзер).
Права, которые нужны панели: создание/клонирование/удаление VM и CT, управление питанием,
`VM.Console` для консоли, `Sys.Audit` для чтения статусов задач.
### Шаблон для VM
Создайте одну VM с cloud-init образом (Ubuntu/Debian cloud image), настройте её и переведите
в шаблон (`qm template <vmid>`). Полученный VMID указывается в панели как `source_vmid` шаблона.
### Шаблон для LXC
Скачайте официальный CT-шаблон через Proxmox (Node → local (storage) → CT Templates → Download),
например `debian-12-standard_12.7-1_amd64.tar.zst`. В панели укажите его как `source_template`
в формате `local:vztmpl/имя_файла.tar.zst`.
## 2. Настройка backend
Скопируйте `backend/.env.example` в `backend/.env` и заполните:
```
SECRET_KEY=<случайная строка> # обязательно смените!
PVE_HOST=https://<ip-вашего-proxmox>:8006
PVE_NODE=pve
PVE_TOKEN_NAME=root@pam!panel
PVE_TOKEN_VALUE=<значение токена>
```
Пароль Postgres задаётся через переменную окружения `POSTGRES_PASSWORD` в shell
или через `.env` рядом с `docker-compose.yml` (compose читает оба файла).
## 3. Настройка CORS
В `backend/.env` укажите `ALLOW_ORIGINS` — список доменов через запятую, с которых
фронтенд будет обращаться к API. По умолчанию это `http://localhost:5173,http://127.0.0.1:5173`.
Для прода обязательно укажите конкретный домен:
```
ALLOW_ORIGINS=https://panel.example.com
```
## 4. Запуск
```bash
# Установите обязательные переменные:
export POSTGRES_PASSWORD=$(openssl rand -hex 16)
# (опционально) задайте порог логирования:
# export LOG_LEVEL=DEBUG
docker compose up -d --build
```
Frontend будет на `http://<host>:5173`. Backend API наружу **не пробрасывается**
все запросы идут через nginx фронтенда по пути `/api/*`. Если нужен прямой доступ
для отладки — раскомментируйте `ports` у сервиса `backend` в `docker-compose.yml`
(только `127.0.0.1:8000:8000`).
Первый, кто зарегистрируется на `/register`, станет администратором — заходите первым сами.
## 5. Установка на TrueNAS SCALE
TrueNAS SCALE умеет запускать произвольные Docker-приложения ("Apps → Discover Apps → Custom App"
либо через "Launch Docker Compose", если версия TrueNAS это поддерживает). Проще всего:
1. Скопируйте папку проекта на TrueNAS (например, в датасет `/mnt/tank/apps/vps-panel`).
2. Заполните `backend/.env`, как описано выше.
3. Из этой директории выполните `docker compose up -d --build` через shell TrueNAS
(System Settings → Shell, либо через SSH), либо оформите как Custom App, указав тот же
`docker-compose.yml` в интерфейсе TrueNAS Apps.
4. Откройте порт 5173 наружу через reverse-proxy (например, встроенный в TrueNAS, либо
отдельный Nginx Proxy Manager), если панель должна быть доступна клиентам извне.
## Консоль VNC — важное примечание
Веб-консоль реализована как websocket-прокси: backend получает от Proxmox тикет
(`vncproxy`) и порт, затем проксирует бинарный поток на `/api/console/ws`, а фронтенд
рисует экран через **noVNC, установленный как npm-пакет** (`@novnc/novnc`, копируется
в `/novnc/` внутри nginx-контейнера на этапе сборки).
Proxmox исторически ожидает на `vncwebsocket` либо cookie-тикет (`PVEAuthCookie`) из обычной
браузерной сессии, либо (в более новых версиях) заголовок `Authorization: PVEAPIToken=...`
в коде (`backend/app/routers/console.py`) используется второй вариант. Если на вашей версии
Proxmox консоль не подключается, скорее всего понадобится либо обновить PVE, либо переключить
аутентификацию панели на логин/пароль с получением `PVEAuthCookie` вместо API-токена именно
для этого запроса — сама бизнес-логика (создание/старт/стоп VPS) от этого не зависит и будет
работать в любом случае.
## Безопасность перед продакшеном
- Смените `SECRET_KEY` и задайте сильный `POSTGRES_PASSWORD`
- Укажите конкретный домен в `ALLOW_ORIGINS` (а не `*`)
- Backend-порт 8000 не должен торчать наружу — закрыт по умолчанию, используйте nginx
- Используйте отдельного Proxmox-пользователя с минимально необходимыми правами для токена
панели, а не `root@pam`
- Не публикуйте `backend/.env` (он в `.gitignore`)
## Структура проекта
```
backend/
app/
main.py — точка входа FastAPI
config.py — переменные окружения (Pydantic v2 Settings)
database.py — SQLAlchemy engine и сессии
security.py — bcrypt + JWT
deps.py — Depends(get_current_user, require_admin)
models.py — таблицы: User, Template, Instance
schemas.py — Pydantic-схемы запросов/ответов
proxmox_client.py — вся логика вызовов Proxmox API (proxmoxer)
routers/
auth.py — регистрация / логин / /me
templates.py — CRUD шаблонов (admin) + импорт из Proxmox
instances.py — создание/список/действия/удаление VPS
admin.py — управление пользователями
console.py — websocket-прокси для VNC-консоли
frontend/
src/
pages/ — Login, Register, Dashboard, InstanceDetail, AdminTemplates, AdminUsers
components/ — InstanceCard, ConsoleViewer
api.js — обёртка над fetch к backend
styles.css — UI-стили
docker-compose.yml
.gitignore
.dockerignore — для backend и frontend
```
## Changelog
### 0.2.0
- 🔒 Удалён закоммиченный `backend/.env` с реальными секретами. **Смените SECRET_KEY и PVE_TOKEN_VALUE!**
- 🔒 Добавлена проверка владельца во всех рутерах `instances.py`
- 🔒 CORS теперь читается из `ALLOW_ORIGINS` (по умолчанию только localhost)
- 🔒 Backend-порт 8000 закрыт снаружи по умолчанию
- 🔒 Postgres-пароль обязателен через `POSTGRES_PASSWORD` (нет дефолта `panel:panel`)
- 🔒 Добавлены security-заголовки и CSP в `nginx.conf`
- 🛠 Заменён `passlib` на прямой `bcrypt` (passlib несовместим с bcrypt 4.x)
- 🛠 Pydantic v2: `SettingsConfigDict` вместо устаревшего `class Config`
- 🛠 Удалены дубли функций/эндпоинтов в `proxmox_client.py` и `instances.py`
- 🛠 Backend запускается от non-root пользователя
- 🛠 Multi-stage Dockerfile для backend (меньше размер образа)
- 🛠 noVNC устанавливается из npm вместо загрузки с CDN
- 🛠 Добавлены healthcheck'и у всех сервисов в docker-compose
- 🛠 Структурированное логирование через `logging`