Обновление файла
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Proxmox VPS Panel
|
# Proxmox VPS Panel
|
||||||
|
|
||||||
Минимальная self-hosted панель для мульти-тенантного управления VPS (VM и LXC) на вашем
|
Self-hosted панель для мульти-тенантного управления VPS (VM и LXC) на вашем
|
||||||
Proxmox VE через API. Backend — FastAPI (Python), frontend — React (Vite), хранилище — Postgres.
|
Proxmox VE через API. Backend — FastAPI (Python), frontend — React (Vite), хранилище — Postgres.
|
||||||
|
|
||||||
Клиенты регистрируются, выбирают шаблон и разворачивают себе VM или LXC-контейнер одной кнопкой;
|
Клиенты регистрируются, выбирают шаблон и разворачивают себе VM или LXC-контейнер одной кнопкой;
|
||||||
@@ -8,22 +8,26 @@ Proxmox VE через API. Backend — FastAPI (Python), frontend — React (Vit
|
|||||||
Первый зарегистрированный пользователь автоматически становится администратором и управляет
|
Первый зарегистрированный пользователь автоматически становится администратором и управляет
|
||||||
шаблонами и списком пользователей.
|
шаблонами и списком пользователей.
|
||||||
|
|
||||||
## Возможности MVP
|
## Возможности
|
||||||
|
|
||||||
- Регистрация/логин (JWT), роли admin / client
|
- Регистрация/логин (JWT), роли admin / client
|
||||||
- Шаблоны VPS: админ создаёт тарифы, привязанные к VM-шаблону (клонирование) или CT-шаблону LXC
|
- Шаблоны VPS: админ создаёт тарифы, привязанные к VM-шаблону (клонирование) или CT-шаблону LXC
|
||||||
- Клиент создаёт инстанс из шаблона — панель сама берёт свободный VMID и вызывает Proxmox API
|
- Клиент создаёт инстанс из шаблона — панель сама берёт свободный VMID и вызывает Proxmox API
|
||||||
- Действия: start / stop / shutdown / reboot / delete
|
- Действия: start / stop / shutdown / reboot / delete
|
||||||
- Веб-консоль через noVNC (websocket-прокси на backend)
|
- Веб-консоль через noVNC (websocket-прокси на backend, noVNC устанавливается из npm)
|
||||||
|
- Проверка владельца во всех эндпоинтах — клиент не может управлять чужими VM
|
||||||
- Всё через docker-compose, разворачивается как Custom App в TrueNAS SCALE
|
- Всё через docker-compose, разворачивается как Custom App в TrueNAS SCALE
|
||||||
|
- Healthcheck-эндпоинты (`/health`, `/health/ready`) и Docker-healthcheck у всех сервисов
|
||||||
|
- Backend работает от непривилегированного пользователя (non-root)
|
||||||
|
|
||||||
## Чего нет в MVP (сознательно, чтобы не раздувать первую версию)
|
## Чего нет (сознательно, чтобы не раздувать первую версию)
|
||||||
|
|
||||||
- Поддержки нескольких Proxmox-нод/кластеров одновременно (сейчас один `PVE_NODE` в конфиге)
|
- Поддержки нескольких Proxmox-нод/кластеров одновременно (сейчас один `PVE_NODE` в конфиге)
|
||||||
- Биллинга и лимитов по ресурсам на пользователя
|
- Биллинга и лимитов по ресурсам на пользователя
|
||||||
- Очереди задач (Celery/Redis) — создание VPS идёт в фоне через `BackgroundTasks` FastAPI,
|
- Очереди задач (Celery/Redis) — создание VPS идёт в фоне через `BackgroundTasks` FastAPI,
|
||||||
для нескольких одновременных заявок этого достаточно, для десятков в секунду — уже нет
|
для нескольких одновременных заявок этого достаточно, для десятков в секунду — уже нет
|
||||||
- Управления сетью/IP-пулами (LXC получает адрес по DHCP, для VM выдаётся из клонированного шаблона)
|
- Управления сетью/IP-пулами (LXC получает адрес по DHCP, для VM выдаётся из клонированного шаблона)
|
||||||
|
- Alembic-миграций (сейчас `create_all()` — для прода рекомендуется добавить)
|
||||||
|
|
||||||
## 1. Подготовка Proxmox
|
## 1. Подготовка Proxmox
|
||||||
|
|
||||||
@@ -52,23 +56,45 @@ Datacenter → Permissions → API Tokens → добавить токен для
|
|||||||
Скопируйте `backend/.env.example` в `backend/.env` и заполните:
|
Скопируйте `backend/.env.example` в `backend/.env` и заполните:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
SECRET_KEY=<случайная строка> # обязательно смените!
|
||||||
PVE_HOST=https://<ip-вашего-proxmox>:8006
|
PVE_HOST=https://<ip-вашего-proxmox>:8006
|
||||||
PVE_NODE=pve
|
PVE_NODE=pve
|
||||||
PVE_TOKEN_NAME=root@pam!panel
|
PVE_TOKEN_NAME=root@pam!panel
|
||||||
PVE_TOKEN_VALUE=<значение токена>
|
PVE_TOKEN_VALUE=<значение токена>
|
||||||
SECRET_KEY=<случайная строка>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. Запуск
|
Пароль 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
|
```bash
|
||||||
|
# Установите обязательные переменные:
|
||||||
|
export POSTGRES_PASSWORD=$(openssl rand -hex 16)
|
||||||
|
# (опционально) задайте порог логирования:
|
||||||
|
# export LOG_LEVEL=DEBUG
|
||||||
|
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
Frontend будет на `http://<host>:5173`, backend API — на `http://<host>:8000`.
|
Frontend будет на `http://<host>:5173`. Backend API наружу **не пробрасывается** —
|
||||||
|
все запросы идут через nginx фронтенда по пути `/api/*`. Если нужен прямой доступ
|
||||||
|
для отладки — раскомментируйте `ports` у сервиса `backend` в `docker-compose.yml`
|
||||||
|
(только `127.0.0.1:8000:8000`).
|
||||||
|
|
||||||
Первый, кто зарегистрируется на `/register`, станет администратором — заходите первым сами.
|
Первый, кто зарегистрируется на `/register`, станет администратором — заходите первым сами.
|
||||||
|
|
||||||
## 4. Установка на TrueNAS SCALE
|
## 5. Установка на TrueNAS SCALE
|
||||||
|
|
||||||
TrueNAS SCALE умеет запускать произвольные Docker-приложения ("Apps → Discover Apps → Custom App"
|
TrueNAS SCALE умеет запускать произвольные Docker-приложения ("Apps → Discover Apps → Custom App"
|
||||||
либо через "Launch Docker Compose", если версия TrueNAS это поддерживает). Проще всего:
|
либо через "Launch Docker Compose", если версия TrueNAS это поддерживает). Проще всего:
|
||||||
@@ -84,8 +110,9 @@ TrueNAS SCALE умеет запускать произвольные Docker-пр
|
|||||||
## Консоль VNC — важное примечание
|
## Консоль VNC — важное примечание
|
||||||
|
|
||||||
Веб-консоль реализована как websocket-прокси: backend получает от Proxmox тикет
|
Веб-консоль реализована как websocket-прокси: backend получает от Proxmox тикет
|
||||||
(`vncproxy`) и порт, затем проксирует бинарный поток на `/console/ws`, а фронтенд рисует
|
(`vncproxy`) и порт, затем проксирует бинарный поток на `/api/console/ws`, а фронтенд
|
||||||
экран через noVNC (`@novnc/novnc`, подключается с CDN).
|
рисует экран через **noVNC, установленный как npm-пакет** (`@novnc/novnc`, копируется
|
||||||
|
в `/novnc/` внутри nginx-контейнера на этапе сборки).
|
||||||
|
|
||||||
Proxmox исторически ожидает на `vncwebsocket` либо cookie-тикет (`PVEAuthCookie`) из обычной
|
Proxmox исторически ожидает на `vncwebsocket` либо cookie-тикет (`PVEAuthCookie`) из обычной
|
||||||
браузерной сессии, либо (в более новых версиях) заголовок `Authorization: PVEAPIToken=...` —
|
браузерной сессии, либо (в более новых версиях) заголовок `Authorization: PVEAPIToken=...` —
|
||||||
@@ -97,11 +124,12 @@ Proxmox консоль не подключается, скорее всего п
|
|||||||
|
|
||||||
## Безопасность перед продакшеном
|
## Безопасность перед продакшеном
|
||||||
|
|
||||||
- Смените `SECRET_KEY` и пароль Postgres по умолчанию
|
- Смените `SECRET_KEY` и задайте сильный `POSTGRES_PASSWORD`
|
||||||
- Ограничьте `allow_origins` в `backend/app/main.py` конкретным доменом фронтенда
|
- Укажите конкретный домен в `ALLOW_ORIGINS` (а не `*`)
|
||||||
- Закройте порт 8000 (backend) наружу, оставьте доступ только через nginx фронтенда
|
- Backend-порт 8000 не должен торчать наружу — закрыт по умолчанию, используйте nginx
|
||||||
- Используйте отдельного Proxmox-пользователя с минимально необходимыми правами для токена
|
- Используйте отдельного Proxmox-пользователя с минимально необходимыми правами для токена
|
||||||
панели, а не `root@pam`
|
панели, а не `root@pam`
|
||||||
|
- Не публикуйте `backend/.env` (он в `.gitignore`)
|
||||||
|
|
||||||
## Структура проекта
|
## Структура проекта
|
||||||
|
|
||||||
@@ -109,12 +137,16 @@ Proxmox консоль не подключается, скорее всего п
|
|||||||
backend/
|
backend/
|
||||||
app/
|
app/
|
||||||
main.py — точка входа FastAPI
|
main.py — точка входа FastAPI
|
||||||
config.py — переменные окружения
|
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
|
models.py — таблицы: User, Template, Instance
|
||||||
|
schemas.py — Pydantic-схемы запросов/ответов
|
||||||
proxmox_client.py — вся логика вызовов Proxmox API (proxmoxer)
|
proxmox_client.py — вся логика вызовов Proxmox API (proxmoxer)
|
||||||
routers/
|
routers/
|
||||||
auth.py — регистрация / логин
|
auth.py — регистрация / логин / /me
|
||||||
templates.py — CRUD шаблонов (admin)
|
templates.py — CRUD шаблонов (admin) + импорт из Proxmox
|
||||||
instances.py — создание/список/действия/удаление VPS
|
instances.py — создание/список/действия/удаление VPS
|
||||||
admin.py — управление пользователями
|
admin.py — управление пользователями
|
||||||
console.py — websocket-прокси для VNC-консоли
|
console.py — websocket-прокси для VNC-консоли
|
||||||
@@ -123,5 +155,26 @@ frontend/
|
|||||||
pages/ — Login, Register, Dashboard, InstanceDetail, AdminTemplates, AdminUsers
|
pages/ — Login, Register, Dashboard, InstanceDetail, AdminTemplates, AdminUsers
|
||||||
components/ — InstanceCard, ConsoleViewer
|
components/ — InstanceCard, ConsoleViewer
|
||||||
api.js — обёртка над fetch к backend
|
api.js — обёртка над fetch к backend
|
||||||
|
styles.css — UI-стили
|
||||||
docker-compose.yml
|
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`
|
||||||
|
|||||||
Reference in New Issue
Block a user