English · Українська · Русский · Polski
Это основная документация для разработчиков и операторов, которые
устанавливают, изменяют, тестируют, выпускают или диагностируют NectarinePanel.
Работа с веб-интерфейсом описана в руководстве пользователя.
Остальные файлы docs/ используются как углублённый технический справочник.
NectarinePanel — модульный монорепозиторий для развёртывания и эксплуатации приложений на одном Ubuntu VPS, а не многосерверный планировщик. FastAPI отвечает за валидацию, авторизацию и состояние, Celery — за долгие задачи, а привилегированные изменения сервера проходят через локальный агент с ограниченным набором операций.
Стек: FastAPI, асинхронный SQLAlchemy, Alembic, PostgreSQL, Valkey, Celery,
Nuxt 4, Vue 3, TypeScript, Pinia, системный агент и необязательный Telegram-бот
на aiogram. Целевая рабочая система — Ubuntu 24.04 LTS. Для разработки нужны Python 3.12+,
поддерживаемый в frontend/package.json Node.js LTS, npm 10+ и Docker Engine с
Compose v2.
backend/ API FastAPI, модели, схемы, сервисы и миграции Alembic
worker/ задачи Celery и обработчик фоновых заданий
agent/ проверяемые системные операции и локальная HTTP-граница
frontend/ Nuxt, компоненты, composable-функции, переводы и тесты
telegram-bot/ необязательный бот владельца
installer/ установщик, обновление, удаление, модули systemd и Nginx
docs/ основные руководства и технические справочники
tests/ тесты репозитория, установщика и контейнерных файлов
scripts/ сценарии обслуживания и проверки
Сохраняйте существующую прагматичную структуру. Не добавляйте слои
domain/application/infrastructure без конкретной необходимости. Маршруты
обрабатывают HTTP, сервисы содержат переиспользуемую бизнес- и инфраструктурную
логику, схемы определяют контракты API, а модели — структуру хранения данных.
Browser -> Nginx -> Nuxt
-> FastAPI -> PostgreSQL
-> Valkey -> Celery worker / scheduler
-> local agent -> root-owned helper -> host
Telegram -> authenticated internal FastAPI endpoints
Типичная асинхронная операция:
- FastAPI аутентифицирует пользователя, проверяет RBAC, валидирует входные данные и создаёт записи задачи и аудита.
- Celery получает идентификаторы и несекретные параметры.
- Обработчик загружает актуальное состояние и зашифрованные учётные данные из хранилища.
- Привилегированная операция отправляется в типизированную конечную точку агента.
- Агент и вспомогательная программа повторно проверяют запрос и преобразуют его в фиксированный список аргументов или ограниченную файловую операцию.
- Обработчик сохраняет ход и результат; интерфейс использует WebSocket с резервным опросом API.
Никогда не добавляйте универсальный запуск команд в агент и не монтируйте сокет Docker в публичную серверную часть. Подробнее: архитектура, безопасность, проекты.
Все команды Python выполняются только через виртуальное окружение репозитория.
python3 -m venv .venv
.venv/bin/pip install -r backend/requirements-dev.txt
cd frontend && npm ci
cd ..
cp .env.example .envЗамените секреты для разработки в .env до передачи окружения другим людям:
openssl rand -hex 32
.venv/bin/python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"docker compose up --build
docker compose exec backend python -m app.cli create-admin --username adminПанель: http://localhost:3000, OpenAPI:
http://localhost:8000/api/v1/docs. Порты разработки привязаны к локальному
интерфейсу. Этот Compose не предназначен для рабочей среды.
Опциональные профили:
docker compose --profile telegram up --build
docker compose --profile adminer up --buildЗапустите PostgreSQL/Valkey или задайте совместимые URL в .env, затем в
отдельных терминалах:
make migrate
make backend
make worker
make scheduler
make agent
make frontendСерверная часть при прямом запуске по умолчанию использует SQLite, но обработчик задач, фоновые задания, ограничение частоты запросов и планировщик требуют Valkey. Для тестов среды выполнения и сервера используйте заглушки или одноразовое окружение; не направляйте среду разработки в рабочее хранилище.
Авторитетная модель — backend/app/core/config.py, стандартные значения — в
.env.example.
| Переменная | Назначение |
|---|---|
ENVIRONMENT |
development, test или рабочее значение; рабочая среда отклоняет стандартные небезопасные секреты. |
DATABASE_URL |
Строка подключения асинхронного SQLAlchemy. |
REDIS_URL |
Valkey/Redis для ограничения запросов, Celery и оперативного состояния. |
JWT_SECRET |
Не менее 32 символов вне локального окружения. |
FIELD_ENCRYPTION_KEY |
Ключ Fernet для сохранённых секретов; обязателен в рабочей среде. |
AGENT_URL, AGENT_TOKEN |
Закрытая конечная точка агента и общий секрет аутентификации. |
STORAGE_ROOT |
Корень проектов, резервных копий, загрузок и состояния сред выполнения. |
CONFIG_ROOT, NGINX_CONFIG_ROOT |
Конфигурация панели и созданных узлов Nginx. |
CORS_ORIGINS |
Разрешённые источники браузера через запятую. |
PUBLIC_BASE_URL |
Публичный URL панели для ссылок и обратных вызовов. |
TELEGRAM_* |
Необязательная конфигурация бота и внутренней аутентификации. |
Не меняйте FIELD_ENCRYPTION_KEY без миграции данных: существующие зашифрованные
поля станут нечитаемыми. Не записывайте в логи объекты настроек, токены, пароли,
закрытые ключи и расшифрованные DSN.
Серверная часть асинхронна. Используйте AsyncSession, схемы Pydantic на
границе API и стабильные HTTP-ошибки вместо внутренних исключений.
При добавлении конечной точки:
- создайте или обновите схему в
backend/app/schemas/; - вынесите переиспользуемую логику в
backend/app/services/, если маршрут смешивает обработку HTTP с бизнес- или инфраструктурной логикой; - до чтения чувствительных данных вызовите
require_global_role(...)илиrequire_project_permission(project_id, permission); - записывайте изменяющие и связанные с безопасностью действия в аудит без открытых секретов;
- добавьте тесты успешного выполнения, валидации, отсутствия аутентификации, запрещённой роли, доступа к чужому проекту и значимых ошибок;
- не ломайте существующий контракт ответа без явно объявленного несовместимого изменения.
Роли owner и admin имеют глобальный доступ к проектам. Доступ ролей
maintainer и viewer задаётся назначением на проект и картой разрешений в
backend/app/services/permissions.py. Скрытие действия в интерфейсе не заменяет
авторизацию на сервере.
Для всех модулей, функций и классов Python обязательны короткие английские строки документации. Используйте безопасные параметры драйверов, проверенные идентификаторы, фиксированные списки аргументов и ограниченный ввод-вывод. Не создавайте команды оболочки из пользовательских данных.
Каждое изменение хранимых данных требует миграции Alembic от текущей вершины:
cd backend
../.venv/bin/alembic heads
../.venv/bin/alembic revision --autogenerate -m "describe change"
../.venv/bin/alembic upgrade head
cd ..Проверьте DDL, имена, индексы, внешние ключи, стандартные значения, порядок обновления и безопасность отката. Протестируйте обновление с предыдущей схемы. Не изменяйте уже применённую миграцию — добавьте исправляющую. Программа обновления создаёт аварийную резервную копию, но миграция всё равно должна быть транзакционной и совместимой с существующими данными, насколько позволяет СУБД.
Celery используется для развёртывания, резервного копирования, операций с базами данных и сертификатами, мониторинга и других продолжительных задач. API должен ставить задачу в очередь, а не удерживать HTTP-соединение.
Правила фоновых задач:
- параметры содержат идентификаторы и несекретные данные, но не учётные данные;
- обработчик заново читает текущее состояние базы данных при старте;
- ход выполнения и ошибки ограничены по размеру и безопасны для интерфейса;
- повторные попытки задаются явно и только для идемпотентных или возобновляемых операций;
- очистка выполняется в
finally; - метаданные фиксируются после успеха внешней операции;
- повторная очистка или удаление по возможности идемпотентны.
В модульных тестах подменяйте границы агента и клиентов, проверяйте успех и частичный отказ. Не требуйте работающий Docker или внешние сервисы.
Агент — привилегированная граница безопасности. HTTP-процесс работает как
vps-panel-agent и передаёт одну проверенную операцию через стандартный ввод
точной вспомогательной программе, принадлежащей суперпользователю и разрешённой
в sudoers.
Новая операция требует:
- строгой типизированной модели запроса и ограничений;
- аутентификации по токену агента;
- разрешения пути внутри допустимого корня после обработки символических ссылок;
- фиксированной программы и аргументов без
shell=True; - ограничения времени и вывода, а также предсказуемых ошибок;
- повторной валидации во вспомогательной программе для операций суперпользователя;
- тестов безопасности на выход за пределы пути, инъекции, ссылки, некорректные данные и отсутствие авторизации;
- минимально необходимых владельцев и системных разрешений.
Если действие нельзя безопасно выразить как фиксированную разрешённую операцию, его не должно быть в API агента.
Nuxt отвечает за представление и состояние клиента. Авторизация, секреты и системная логика остаются в серверной части. Используйте существующие компоненты, переменные CSS, значки Tabler, composable-функции и адаптивные шаблоны; не добавляйте зависимость ради небольшой тестируемой вспомогательной функции.
frontend/pages/ страницы маршрутов
frontend/components/ переиспользуемые компоненты интерфейса
frontend/composables/ API, локализация, разрешения и общая логика
frontend/stores/ состояние Pinia
frontend/locales/ каталоги EN, UK, RU и PL
frontend/types/ типы интерфейса
frontend/tests/ тесты Vitest
Каждая видимая строка должна использовать функцию локализации и существовать во всех четырёх каталогах. Ключи перевода должны быть смысловыми и стабильными, а даты и числа — форматироваться с учётом языка. Для страниц нужны явные состояния загрузки, ошибки, пустого результата, запрета доступа и успеха. Необратимые действия требуют диалога подтверждения и, где поддерживается, подтверждения на сервере.
cd frontend
npm run lint
npm run typecheck
npm run test
npm run build
cd ..Во время разработки запускайте целевые тесты:
.venv/bin/python -m pytest backend/tests/test_projects.py
.venv/bin/python -m pytest agent/tests/test_security.py
cd frontend && npm run test -- projects-utils && cd ..Перед коммитом выполните полную проверку:
make checkОна включает проверку и форматирование Ruff, mypy, ESLint, проверку типов Nuxt, тесты Python и интерфейса, рабочую сборку, аудит npm, синтаксис сценариев оболочки и конфигурацию Compose. При изменении установщика или образов дополнительно:
docker compose --profile telegram build backend frontend worker agent telegram-bot
sudo ./installer/install.sh --domain panel.example.com --email admin@example.com --dry-runНовая логика требует тестов, включая граничные случаи. По умолчанию предпочитайте модульные тесты; интеграционные добавляйте там, где заглушки не доказывают поведение на границе базы данных, очереди, агента или файловой системы.
/opt/nectarine-panel/ установленное приложение
/etc/nectarine-panel/ конфигурация сервисов и секреты
/etc/nginx/vps-panel/ созданные узлы проектов
/srv/vps-panel/projects/{id}/ релизы, текущая ссылка, общие данные, загрузки и логи
/srv/vps-panel/backups/ копии проектов, баз данных и всей панели
/srv/vps-panel/minecraft/{id}/ данные среды Minecraft
Релизы неизменяемы, а активация атомарно заменяет current. Постоянные данные
находятся в shared/, а не в релизе или несмонтированном слое контейнера.
Распаковка отклоняет выход за пределы каталога, внешние ссылки, специальные
файлы, чрезмерное количество элементов и архивные бомбы. Восстановление
проверяет контрольную сумму, тип, совместимость и цель до замены данных.
Устанавливайте проверенный релиз с тегом от имени суперпользователя:
sudo ./installer/install.sh \
--domain panel.example.com \
--email admin@example.comУстановщик создаёт отдельных пользователей, PostgreSQL/Redis, хранилище, окружение Python, сборку интерфейса, миграции, модули systemd, Nginx, вспомогательную программу агента, первого владельца и TLS. Неуказанный пароль администратора генерируется и показывается один раз.
| Параметр | Назначение |
|---|---|
--domain, --email |
Имя хоста панели и адрес почты для Let's Encrypt. |
--admin-user, --admin-password |
Первый владелец; пароль минимум 12 символов. |
--storage-root |
Абсолютный корень постоянных данных. |
--telegram-token, --telegram-owner-id |
Необязательная настройка бота. |
--public-ip |
Явно заданный публичный адрес. |
--source |
Установка из доверенного локального дерева исходного кода. |
--repository, --ref |
Репозиторий и закреплённая ревизия Git. |
--max-upload-mb |
Ограничение загрузки от 1 до 4096 МиБ. |
--backend-port, --frontend-port, --agent-port, --adminer-port |
Уникальные локальные порты 1024–65535. |
--non-interactive |
Ошибка вместо запроса недостающих значений. |
--skip-ssl |
HTTP без выпуска сертификата. |
--dry-run |
Валидация без установки. |
sudo /opt/nectarine-panel/installer/update.sh --ref vX.Y.Z
sudo /opt/nectarine-panel/installer/uninstall.shupdate.sh поддерживает --source, --repository, --ref, --dry-run,
создаёт аварийные резервные копии, применяет миграции и проверяет состояние.
uninstall.sh сохраняет постоянные данные без явно подтверждённого --purge;
также доступны --yes и --dry-run.
Не передавайте непроверенную изменяемую ветку напрямую в оболочку суперпользователя. Подробнее: установка, выпуск релиза.
Начинайте со статуса сервисов и ограниченных свежих логов:
sudo systemctl status \
vps-panel-backend vps-panel-frontend vps-panel-worker \
vps-panel-scheduler vps-panel-agent vps-panel-telegram-bot
sudo journalctl -u vps-panel-backend -n 200 --no-pager
sudo journalctl -u vps-panel-worker -n 200 --no-pager
sudo journalctl -u vps-panel-agent -n 200 --no-pager
sudo nginx -t
curl -fsS http://127.0.0.1:8000/api/v1/healthИспользуйте фактический порт серверной части. Проверьте PostgreSQL, Redis,
Docker, место и индексные дескрипторы диска, DNS, порты 80/443 и владельцев
файлов в корне хранилища. Ответ 502 от операции проекта обычно означает, что
серверная часть не завершила проверенное действие агента; сопоставьте логи
серверной части, обработчика и агента по времени и идентификатору задачи.
Не публикуйте полные файлы окружения и логи без удаления чувствительных данных. Удаляйте токены, cookie, пароли, закрытые URL и ключи SSH, строки подключения к базе и пользовательские данные. Перед ручным исправлением создайте резервную копию и определите владельца состояния. Не обходите агент разовыми изменениями от суперпользователя, которые панель не сможет согласовать.
Делайте коммиты сфокусированными, документируйте миграции, безопасность, совместимость резервных копий и влияние на эксплуатацию. Перед запросом на слияние:
- проверьте
git diffиgit status; - выполните
make checkи нужные сборки контейнеров; - убедитесь, что новый текст интерфейса есть в четырёх языковых каталогах;
- убедитесь, что не добавлены
.env, базы данных, архивы, токены, закрытые ключи, внутренние имена хостов или созданные файлы сборки; - обновите руководство пользователя при изменении рабочего процесса, а руководство разработчика или справочник — при изменении внутренней логики.
Для релиза обновите журнал изменений и версию, проверьте миграции, создайте
подписанный тег vX.Y.Z, опубликуйте контрольные суммы и инструкции по
обновлению и откату, проверьте установку на чистую Ubuntu 24.04 и восстановление
на временном сервере. Следуйте
CONTRIBUTING.md, SECURITY.md и
releasing.md.