diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..05df6f1 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,487 @@ +# Установка Docker и развёртывание Proxmox VPS Panel + +Полная пошаговая инструкция: от чистого Linux-сервера до работающей панели +управления VPS на базе Proxmox VE. + +Документ рассчитан на Debian 12 / Ubuntu 22.04+ (это самый частый вариант +для Proxmox-хоста и для отдельной VM/LXC под панель). Для других дистрибутивов +есть отдельный раздел ниже. + +--- + +## 1. Требования + +### Аппаратные (для VM/LXC, где будет крутиться панель) + +| Ресурс | Минимум | Рекомендуется | +|---|---|---| +| CPU | 1 vCPU | 2 vCPU | +| RAM | 1 ГБ | 2 ГБ | +| Диск | 8 ГБ | 20 ГБ (с запасом под бэкапы Postgres) | +| Сеть | Доступ до API Proxmox по TCP 8006 | то же | + +### Программные + +- Linux с ядром ≥ 3.10 (для Docker Engine) +- Права `root` или пользователь из группы `sudo` +- Открытый порт `5173` (frontend, nginx) — если панель должна быть доступна извне +- Доступ до Proxmox VE по HTTPS (порт 8006) + +### Сетевые + +- Сервер панели должен «видеть» Proxmox API (`https://:8006/api2/json`) +- Proxmox в свою очередь должен «видеть» сеть, в которой будут создаваться VM/CT + (обычно это один и тот же `vmbr0` / bridge) + +--- + +## 2. Установка Docker Engine + Compose + +> Docker Engine — это сервер контейнеров (демон `dockerd`). +> Docker Compose — это инструмент для описания multi-container приложений в YAML +> (формат `compose.yaml`/`docker-compose.yml`). + +### 2.1. Debian / Ubuntu (рекомендуемый путь) + +```bash +# 1. Обновляем индекс пакетов и ставим prerequisites +sudo apt-get update +sudo apt-get install -y \ + ca-certificates \ + curl \ + gnupg \ + lsb-release + +# 2. Добавляем официальный GPG-ключ Docker +sudo install -m 0755 -d /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/debian/gpg \ + | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +sudo chmod a+r /etc/apt/keyrings/docker.gpg + +# 3. Добавляем репозиторий Docker +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ + https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" \ + | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + +# 4. Ставим Docker Engine + CLI + Compose plugin +sudo apt-get update +sudo apt-get install -y \ + docker-ce \ + docker-ce-cli \ + containerd.io \ + docker-buildx-plugin \ + docker-compose-plugin +``` + +> Для Ubuntu замените `debian` на `ubuntu` в строке с URL репозитория, остальное +> идентично. + +### 2.2. Альтернатива: официальный `install.sh` + +Если не хочется возиться с репозиторием — Docker предоставляет скрипт, который +сделает всё сам: + +```bash +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +``` + +Этот же скрипт работает на Debian, Ubuntu, RHEL, Fedora, CentOS, AlmaLinux, +Rocky и т. д. — внутри он сам определяет дистрибутив. + +### 2.3. Другие дистрибутивы (краткая сводка) + +| Дистрибутив | Что делать | +|---|---| +| Fedora / RHEL / Alma / Rocky | `sudo dnf -y install dnf-plugins-core && sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo && sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin` | +| Arch / Manjaro | `sudo pacman -S docker docker-compose` | +| openSUSE | `sudo zypper install docker docker-compose` | +| TrueNAS SCALE | см. раздел 8 — там Docker уже встроен | + +--- + +## 3. Постустановочная настройка Docker + +### 3.1. Включаем автозапуск демона + +```bash +sudo systemctl enable --now docker +sudo systemctl status docker # должно быть active (running) +``` + +### 3.2. Разрешаем пользователю работать без `sudo` + +По умолчанию `docker` требует root. Чтобы не набирать `sudo` каждый раз: + +```bash +sudo usermod -aG docker $USER +# После этого нужно ПЕРЕЛОГИНИТЬСЯ (или выполнить newgrp docker): +newgrp docker +``` + +Проверка: + +```bash +docker version +docker compose version +docker run --rm hello-world +``` + +Если `hello-world` скачался и напечатал приветствие — Docker готов. + +### 3.3. Ограничение логов (опционально, но полезно) + +Чтобы контейнеры не съедали диск логами, создайте `/etc/docker/daemon.json`: + +```json +{ + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + } +} +``` + +И перезапустите демон: + +```bash +sudo systemctl restart docker +``` + +--- + +## 4. Подготовка Proxmox + +Эти шаги делаются в **веб-интерфейсе Proxmox**. + +### 4.1. API-токен + +1. **Datacenter → Permissions → API Tokens → Add** +2. User: `root@pam` (для теста; в проде лучше завести отдельного пользователя — + см. раздел «Безопасность» ниже) +3. Token ID: например `panel` +4. Privilege Separation: **выключить** (чтобы токен наследовал все права владельца) +5. Скопируйте **Secret** — он показывается один раз. + +В итоге получите пару: + +``` +PVE_TOKEN_NAME=root@pam!panel +PVE_TOKEN_VALUE=<тот самый секрет> +``` + +Права, которые нужны панели: + +- `VM.Allocate`, `VM.PowerMgmt`, `VM.Config.Disk`, `VM.Config.Network`, + `VM.Config.CPU`, `VM.Config.Memory`, `VM.Config.Cloudinit`, + `VM.Clone`, `VM.Audit`, `VM.Snapshot`, `VM.Backup` +- `Sys.Audit` (для чтения статусов задач Proxmox) +- Аналогичные права для `PVEAdmin` / `PVEAuditor` на ветке `/` + +В тестовой среде проще всего выдать роль `PVEAdmin` на корень `/`. + +### 4.2. Шаблон VM (для VM-инстансов) + +1. Скачайте cloud-образ, например Ubuntu 22.04: + ```bash + wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img + ``` +2. В Proxmox создайте VM, в **Hardware → CD/DVD** укажите этот образ. +3. В **Cloud-Init → User**, **Password**, **SSH key** — заполните значения по умолчанию + (панель их перезапишет своими). +4. Запустите VM, убедитесь, что cloud-init отработал и сеть поднялась. +5. Выключите VM и превратите её в шаблон: + ```bash + qm template + ``` + VMID запомните — он пойдёт в поле `source_vmid` шаблона в панели. + +### 4.3. Шаблон LXC (для CT-инстансов) + +1. Узел → **local (storage)** → **CT Templates → Template** → вкладка **Download** +2. Скачайте, например, `debian-12-standard_12.7-1_amd64.tar.zst` +3. Готово. В панели поле `source_template` будет иметь вид: + ``` + local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst + ``` + +--- + +## 5. Клонирование и настройка репозитория + +### 5.1. Клонируем + +```bash +git clone https://gitea.nasweb.ru/host/Proxmox-VPS-Panel.git +cd Proxmox-VPS-Panel +``` + +Структура должна выглядеть так: + +``` +Proxmox-VPS-Panel/ +├── backend/ +├── frontend/ +├── docker-compose.yml +└── .gitignore +``` + +### 5.2. Готовим `.env` для backend + +```bash +cd backend +cp .env.example .env +nano .env # или vim / любой редактор +``` + +Заполните: + +```env +# Обязательно смените! Сгенерировать: openssl rand -hex 32 +SECRET_KEY=<случайная_строка_минимум_32_символа> + +# Proxmox API +PVE_HOST=https://192.168.31.2:8006 +PVE_NODE=pve +PVE_TOKEN_NAME=root@pam!panel +PVE_TOKEN_VALUE=<ваш_секрет_токена> + +# CORS — домен фронтенда через запятую (без пробелов) +ALLOW_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 + +# Пароль БД — ОБЯЗАТЕЛЬНО должен совпадать с POSTGRES_PASSWORD +# из .env рядом с docker-compose.yml +DATABASE_URL=postgresql://panel:<тот_же_пароль_что_и_POSTGRES_PASSWORD>@db:5432/panel +``` + +> ⚠️ `DATABASE_URL` обычно собирается автоматически внутри `docker-compose.yml` +> через `${POSTGRES_USER}` и `${POSTGRES_PASSWORD}`. Если вы переопределяете +> его здесь — убедитесь, что хост = `db` (имя сервиса в compose), а не +> `localhost`, иначе backend не достучится до Postgres. + +### 5.3. Генерируем секреты + +```bash +# SECRET_KEY для подписи JWT +openssl rand -hex 32 + +# POSTGRES_PASSWORD для базы данных +openssl rand -hex 16 +``` + +### 5.4. Создаём `.env` рядом с `docker-compose.yml` + +Вернитесь в корень проекта: + +```bash +cd .. +cat > .env <<'EOF' +POSTGRES_USER=panel +POSTGRES_PASSWORD=<тот_самый_пароль_из_openssl_rand_hex_16> +POSTGRES_DB=panel +FRONTEND_PORT=5173 +EOF +chmod 600 .env # только владелец может читать — там секрет +``` + +> Этот файл уже в `.gitignore`, но на всякий случай не пушьте его. + +--- + +## 6. Запуск панели + +### 6.1. Поднимаем стек + +```bash +docker compose pull # подтянуть базовые образы (postgres, alpine) +docker compose up -d --build +``` + +- `--build` нужен, потому что backend и frontend собираются из исходников + (multi-stage Dockerfile внутри `backend/` и `frontend/`) +- `-d` запускает в фоне + +### 6.2. Проверяем, что всё поднялось + +```bash +docker compose ps +``` + +Все три сервиса (`db`, `backend`, `frontend`) должны быть в статусе `running` +или `healthy`. Healthcheck у backend проверяет `http://localhost:8000/health`, +у frontend — `http://localhost:5173/`, у БД — `pg_isready`. + +Логи в реальном времени: + +```bash +docker compose logs -f +# или только backend: +docker compose logs -f backend +``` + +### 6.3. Проверка API вручную + +```bash +curl http://localhost:5173/api/health +# {"status":"ok"} + +curl http://localhost:5173/api/health/ready +# {"status":"ready","db":"ok"} +``` + +> `/api/*` проксируется nginx-фронтенда на backend, поэтому порт 8000 наружу +> не торчит. + +### 6.4. Открываем UI + +В браузере: + +``` +http://:5173 +``` + +1. Нажмите **Register** — зарегистрируйтесь. +2. **Первый зарегистрированный пользователь автоматически становится админом.** + Это важно — зайдите первым сами. +3. Войдите как админ, откройте **Admin → Templates**, создайте шаблон: + + - **Type**: `vm` или `lxc` + - **Name**: что увидит клиент (например, `Ubuntu 22.04 / 1 vCPU / 1 GB`) + - **Cores / Memory / Disk**: сколько ресурсов получит инстанс + - **Source VMID** (для `vm`): VMID вашего VM-шаблона из шага 4.2 + - **Source template** (для `lxc`): путь вида + `local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst` + +4. Выйдите из админа, зарегистрируйте второго пользователя (или попросите + клиента) — он уже будет `client` и увидит шаблон в дашборде. + +--- + +## 7. Типовые ошибки и что с ними делать + +| Симптом | Причина | Решение | +|---|---|---| +| `POSTGRES_PASSWORD is required` при `up` | не задан `POSTGRES_PASSWORD` в `.env` рядом с compose | см. шаг 5.4 | +| Backend падает с `connection refused` на `db:5432` | compose стартует backend раньше, чем БД приняла соединения | уже лечится через `depends_on: condition: service_healthy`; подождите минуту | +| `pve authentication failed` при создании VPS | неверный `PVE_TOKEN_VALUE` или истёк токен | пересоздайте токен в Proxmox и обновите `.env`, затем `docker compose restart backend` | +| CORS-ошибка в браузере: «blocked by CORS policy» | в `ALLOW_ORIGINS` нет домена, с которого открываете панель | добавьте свой домен/IP в `backend/.env` → `ALLOW_ORIGINS`, затем `docker compose restart backend` | +| `permission denied` при `qm template` | вы выполняете не от root | `sudo qm template ` | +| Не приходит IP созданной VM | в VM-шаблоне не установлен `qemu-guest-agent` и не включён в Proxmox | установите `qemu-guest-agent` в шаблоне, в опциях VM включите `Run guest agent on boot` | +| Долго создаётся VM/CT | это нормально — `qmclone`/`pct clone` могут занимать минуты на больших дисках | следите за прогрессом через `docker compose logs -f backend` или UI Proxmox | + +--- + +## 8. Установка на TrueNAS SCALE + +TrueNAS SCALE (Cobia / Dragonfish / Electric Eel / Fangtooth) уже содержит +Docker Engine и Compose из коробки. Дополнительно ставить ничего не нужно. + +### 8.1. Вариант A: «Custom App» через UI + +1. **Apps → Discover Apps → Custom App** +2. **Application Name**: `vps-panel` +3. В секции **Container Images / Compose** переключитесь на режим + «Custom Compose`» и вставьте содержимое нашего `docker-compose.yml` + (или положите файлы в датасет и смонтируйте их как `/docker-compose.yml`). +4. Переменные окружения задайте через UI: + - `POSTGRES_USER` = `panel` + - `POSTGRES_PASSWORD` = `` + - `POSTGRES_DB` = `panel` + - `FRONTEND_PORT` = `5173` + - На отдельной вкладке для сервиса `backend` добавьте все `PVE_*` и + `SECRET_KEY`, `ALLOW_ORIGINS`, плюс `env_file: ./backend/.env` +5. **Storage**: + - Для сервиса `db` смонтируйте `panel_db` (named volume) или + путь на датасете типа `/mnt/tank/apps/vps-panel/db` +6. Нажмите **Install**. Статус появится в **Installed Applications**. + +### 8.2. Вариант B: shell + `docker compose` + +```bash +# Заходим на TrueNAS по SSH или открываем System Settings → Shell +cd /mnt/tank/apps/vps-panel # путь, куда положили репозиторий +cp backend/.env.example backend/.env +nano backend/.env # заполняем +cat > .env <<'EOF' +POSTGRES_USER=panel +POSTGRES_PASSWORD= +POSTGRES_DB=panel +FRONTEND_PORT=5173 +EOF + +docker compose up -d --build +``` + +### 8.3. Reverse-proxy + +TrueNAS Apps умеет автоматически прокидывать порты. Если нужен внешний доступ: + +- Встроенный reverse-proxy TrueNAS (например, через приложение + `nginx-proxy-manager` или `traefik`) +- Или собственный reverse-proxy (Caddy, Nginx) с TLS через Let's Encrypt + +Обязательно укажите итоговый внешний домен в `backend/.env → ALLOW_ORIGINS`, +иначе CORS заблокирует запросы. + +--- + +## 9. Обновление панели + +```bash +cd Proxmox-VPS-Panel +git pull +docker compose pull +docker compose up -d --build +docker compose restart +``` + +Миграций БД нет (используется `Base.metadata.create_all()`), так что апгрейд +проходит без ручных шагов. Перед большими апгрейдами рекомендуется +сделать бэкап volume `panel_db`: + +```bash +docker compose stop db +docker run --rm \ + -v panel_db:/from \ + -v $(pwd)/backups:/to \ + alpine sh -c "tar czf /to/panel_db_$(date +%F).tgz -C /from ." +docker compose start db +``` + +--- + +## 10. Удаление + +```bash +cd Proxmox-VPS-Panel +docker compose down # остановить и удалить контейнеры +docker compose down -v # + удалить volume panel_db (ВСЕ ДАННЫЕ БД) +docker image prune -a # удалить неиспользуемые образы +``` + +Удаление **не трогает** VM и LXC на Proxmox — их панель создаёт через API, +и они продолжат жить независимо. + +--- + +## Краткий чек-лист «поставил и работает» + +``` +[ ] Docker Engine + Compose установлены +[ ] docker compose version показывает v2+ +[ ] В Proxmox создан API-токен +[ ] В Proxmox есть VM-шаблон (если планируются VM) +[ ] В Proxmox есть CT-шаблон (если планируются LXC) +[ ] git clone репозитория выполнен +[ ] backend/.env заполнен, SECRET_KEY сменён +[ ] POSTGRES_PASSWORD сгенерирован и записан в .env рядом с compose +[ ] docker compose up -d --build — все 3 сервиса running/healthy +[ ] curl /api/health → {"status":"ok"} +[ ] В браузере открыт http://:5173, зарегистрирован админ +[ ] Создан хотя бы один шаблон в Admin → Templates +``` + +Если все галочки стоят — панель готова к работе.