docs: revise the one-command install stage
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
Deploy to Production / Trigger production update (push) Has been cancelled

deploy.sh already covers most of the installer (OS detection, Docker setup,
random secret generation, nginx, TLS, image build, pve CLI), so the stage is
about publishing a thin bootstrap rather than writing one from scratch.

Records the decisions taken: the bootstrap detects its environment and
creates an LXC when run on a PVE host, the repository is public, and images
keep being built locally. On a PVE host the node can register itself without
a password via pvesh, reusing the token provisioning from stage 1.
This commit is contained in:
markmorado
2026-07-24 04:43:07 +05:00
parent 075b8cdaaa
commit 6a4da4f80b

View File

@@ -67,37 +67,79 @@ load average, сеть in/out, swap, корневая ФС. Пресеты `1h/2
## ⬜ Этап 3. Установка одной командой
**Цель.** Пользователь разворачивает панель на своём сервере одной командой,
вместе с ней устанавливается консольный хелпер `pve`.
**Цель.** Установка панели одной командой в терминале:
**Что уже есть.** `deploy.sh` (36 КБ, основная логика развёртывания), `pve`
(CLI-хелпер), каталог `systemd/` с юнитами, `compose.yml`. Не хватает тонкой
обёртки-установщика и публикации.
```
curl -fsSL https://get.<домен> | bash
```
**Шаги.**
1. Написать `install.sh` в корне репозитория:
- проверка ОС и наличия Docker + docker compose v2, понятная ошибка вместо
падения на середине;
- клонирование репозитория в `/opt/pvemanager` (путь настраиваемый);
- генерация `.env` со случайными секретами;
- `docker compose up -d`;
- установка `pve` в `/usr/local/bin`, установка systemd-юнита;
- идемпотентность: повторный запуск обновляет существующую установку, а не
ломает её.
2. Убрать дефолт `POSTGRES_PASSWORD: pvemanager_secure_password` из `compose.yml`
— в публичной поставке пароль должен генерироваться, а не иметь значение
по умолчанию.
3. Опубликовать скрипт (raw.githubusercontent или короткий домен), в README
дать два варианта: `curl … | bash` и «скачать → прочитать → запустить» с
публикацией sha256.
4. Документировать удаление и обновление.
**Что уже есть — важно не переписывать.** `deploy.sh` (1107 строк) уже
покрывает почти весь установщик: `detect_os`, `install_docker`,
`install_dependencies`, `check_requirements`, `create_env_file` (генерирует
случайные `POSTGRES_PASSWORD`, `SECRET_KEY` и `FERNET_KEY` через openssl),
`setup_nginx_config`, `obtain_ssl_certificate` (Let's Encrypt),
`build_images_resilient`, `check_stale_db_volume`, `deploy_with_nginx`,
`deploy_standalone`, `install_update_watchdog`, `install_pve_cli`.
**Готово, когда** на чистой Debian/Ubuntu-машине одна команда поднимает
работающую панель, `pve --help` отвечает, повторный запуск скрипта не ломает
установку.
Задача этапа — **не написать установщик, а опубликовать тонкий загрузчик**
(ориентировочно 60–100 строк), который доводит пользователя до `deploy.sh`.
**Риски.** `curl | bash` — потенциальный вектор атаки; обязательны контрольная
сумма и альтернативный путь установки.
**Принятые решения.**
- Загрузчик **определяет среду сам** (наличие `/etc/pve`).
- Репозиторий на момент запуска **публичный** — загрузчик просто клонирует его.
- Образы **собираются на месте**, как сейчас; publish в registry не делаем.
### Ветка A — обычная машина (Debian/Ubuntu с Docker)
Загрузчик клонирует репозиторий в `/opt/pvemanager` и передаёт управление
`deploy.sh`. Новой логики почти не требуется.
### Ветка B — запуск на самом PVE-хосте
Docker на гипервизоре ставить не следует, поэтому здесь загрузчик:
1. Создаёт LXC-контейнер (Debian 12) через `pct`: скачивает шаблон, если его
нет, поднимает контейнер с сетью через DHCP на `vmbr0`, параметры (vmid,
storage, bridge, ресурсы) настраиваются переменными окружения.
2. Внутри контейнера выполняет ту же ветку A.
3. **Автоматически регистрирует эту ноду в поднятой панели.** Скрипт работает
как root на самом хосте, поэтому может создать токен локально:
`pvesh create /access/users/root@pam/token/pvemanager --privsep 0`,
и передать его панели — пароль не нужен вообще. Это переиспользует
механизм из этапа 1 (`token_provisioning.py`).
4. Печатает адрес панели и учётные данные первого входа.
Результат ветки B: после одной команды пользователь получает работающую панель
с уже подключённым сервером.
### Инфраструктура раздачи
- Домен `get.<домен>` под контролем проекта, TLS обязателен.
- Раздача статики (Cloudflare Pages/Worker или R2). Отдавать
`Content-Type: text/plain` и короткий `Cache-Control`, иначе правки скрипта
будут доезжать до пользователей часами.
- **Пиннинг версии:** по умолчанию тянуть последний git-**тег**, а не `main`,
иначе любой промежуточный коммит немедленно уезжает всем, кто ставит панель
в этот момент. Переменная `PVEMANAGER_VERSION=v1.2.3` для явного выбора.
- Идемпотентность: повторный запуск = обновление. Встроиться в существующий
`install_update_watchdog`, а не дублировать его.
### Безопасность
- Публиковать sha256 загрузчика; в README дать второй путь установки
(«скачать → прочитать → запустить»).
- Не вызывать `sudo` неявно — честно требовать root.
- Печатать план действий (что будет установлено и куда) до начала работы.
- Убрать fallback `${POSTGRES_PASSWORD:-pvemanager_secure_password}` из
`compose.yml`: `create_env_file` уже генерирует пароль, но при отсутствии
`.env` стек молча поднимется с предсказуемым паролем.
**Готово, когда:**
- на чистой Debian/Ubuntu-машине одна команда поднимает работающую панель;
- на PVE-хосте та же команда создаёт LXC, ставит панель внутрь и регистрирует
ноду без ввода пароля;
- `pve --help` отвечает;
- повторный запуск обновляет установку, не ломая её.
## ⬜ Этап 4. Интеграция с Proxmox Backup Server