# Local Deployment Plan ## Domains Для локальной разработки целевая схема: ```text 127.0.0.1 auth.local.nodedc 127.0.0.1 launcher.local.nodedc 127.0.0.1 task.local.nodedc 127.0.0.1 agents.local.nodedc 127.0.0.1 tender.local.nodedc 127.0.0.1 onec.local.nodedc 127.0.0.1 dm.local.nodedc ``` На macOS изменение `/etc/hosts` требует admin password. Если агент не может выполнить `sudo`, эти строки нужно добавить вручную. ## Current local apps Launcher сейчас запускается как Vite app + local BFF из: ```text /Users/dcconstructions/Downloads/mnt/data/nodedc_launcher ``` В dev режиме `npm run dev` запускает BFF на `:5173`; Vite подключен как middleware. Чистый Vite режим сохранен как `npm run dev:vite`. Task Manager сейчас доступен как Plane self-host runtime: ```text http://localhost:8090 ``` Runtime: ```text /Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-app ``` Source fork: ```text /Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src ``` ## Target local flow Первый local infra milestone: ```text auth.local.nodedc -> Authentik launcher.local.nodedc -> Launcher web/backend task.local.nodedc -> Plane proxy/runtime ``` Все внешние запросы идут через reverse proxy. На этом этапе reverse proxy реализуется через Caddy, а Authentik запускается за ним без прямой публикации host ports. Для текущей локальной машины proxy image задан как `nodedc/plane-proxy:ru`: это уже существующий Caddy-based image из Plane-стенда. На чистой машине можно заменить `PLATFORM_PROXY_IMAGE` на `caddy:2-alpine`. Текущие приложения подключаются как внешние upstream: ```text launcher.local.nodedc -> host.docker.internal:5173 task.local.nodedc -> host.docker.internal:8090 ``` Это сохраняет Launcher и Plane в их текущих репозиториях и runtime-папках. ## Environment Базовые переменные должны жить в: ```text platform/infra/.env ``` Пример значений хранится в: ```text platform/infra/.env.example ``` Для генерации локальных secrets: ```bash cd /Users/dcconstructions/Downloads/mnt/NODEDC/platform ./infra/scripts/init-dev-env.sh ``` Скрипт создает `platform/infra/.env`, выставляет права `600` и не перезаписывает существующий файл. ## Start commands ```bash cd /Users/dcconstructions/Downloads/mnt/NODEDC/platform docker compose --env-file infra/.env -f infra/docker-compose.dev.yml up -d ``` ## Authentik bootstrap After Authentik is healthy, bootstrap local NODE.DC identity objects: ```bash NODEDC_BOOTSTRAP_ADMIN_EMAIL=dcctouch@gmail.com infra/scripts/bootstrap-authentik-dev.sh ``` This creates: - `nodedc:superadmin`; - `nodedc:launcher:admin`; - `nodedc:launcher:user`; - `nodedc:taskmanager:admin`; - `nodedc:taskmanager:user`; - `NODE.DC Launcher` application with OAuth2/OIDC provider; - `NODE.DC Task Manager` application with OAuth2/OIDC provider; - group bindings for application access. OIDC providers must have a signing key. Without it Authentik returns an empty JWKS (`{}`), and Launcher callback fails token validation. The script fills missing `LAUNCHER_OIDC_CLIENT_SECRET` and `PLANE_OIDC_CLIENT_SECRET` values in ignored `infra/.env`. Secrets are not committed. Проверка: ```bash docker compose --env-file infra/.env -f infra/docker-compose.dev.yml ps curl -I -H 'Host: auth.local.nodedc' http://127.0.0.1/ curl -I -H 'Host: launcher.local.nodedc' http://127.0.0.1/ curl -I -H 'Host: task.local.nodedc' http://127.0.0.1/ ``` Текущая локальная проверка: ```text auth.local.nodedc -> 302 Authentik authentication flow launcher.local.nodedc -> 200 Launcher/Vite HTML task.local.nodedc -> 200 Plane HTML ``` Эти проверки выполнены через `curl` с `Host` header. Для проверки в браузере нужны записи в `/etc/hosts`. ## Authentik version note Официальный compose Authentik для текущей ветки 2026.2 использует PostgreSQL, `server` и `worker`. Redis, указанный в раннем ТЗ как ожидаемый сервис, в актуальном официальном compose не используется. Если позже будет выбран старый pinned Authentik или отдельная HA-схема, Redis надо вернуть отдельной задачей. ## Implementation order 1. Согласовать локальные domain/port bindings. 2. Добавить reverse proxy config. 3. Поднять Authentik server, worker и Postgres. 4. Прокинуть Authentik за proxy с корректными headers. 5. Подключить текущий Launcher как внешний сервис или через compose service. 6. Подключить текущий Plane runtime как внешний service target. 7. После стабилизации собрать воспроизводимый compose. ## Notes Текущий Plane runtime не переносится на нулевом этапе. Любое изменение `plane-app/plane.env`, volumes или startup scripts делается только после backup и отдельной задачи.