docs: add persistent project context and NPM deployment notes

This commit is contained in:
2026-04-13 20:15:51 +00:00
parent 89f705c533
commit 6095d53854
3 changed files with 141 additions and 2 deletions

View File

@@ -164,6 +164,38 @@ docker compose logs -f api traefik
https://<PUBLIC_HOST>/admin
```
## 5.2 Вариант С Nginx Proxy Manager (NPM)
Если на сервере уже используется NPM, внешний трафик можно вести через него, а Traefik оставить только внутренним роутером проекта.
В этом репозитории уже настроены внутренние порты:
- `127.0.0.1:2288 -> traefik:443` (HTTPS upstream)
- `127.0.0.1:8288 -> traefik:80` (HTTP upstream, технический)
Важно: Traefik убирать нельзя, он нужен для динамических маршрутов сессий (`/s/*`, `/svc/*`).
Как настроить NPM:
1. Создать `Proxy Host` для домена (например `stend.example.com`):
- `Forward Hostname / IP`: `127.0.0.1`
- `Forward Port`: `2288`
- `Scheme`: `https`
- включить `Websockets Support`
2. На вкладке SSL в NPM выпустить/подключить сертификат для домена.
3. В `.env` проекта оставить:
- `PUBLIC_HOST=stend.example.com`
4. Перезапустить проект:
```bash
docker compose up -d --build
```
После этого вход в портал и сессии будут работать через NPM, а Traefik останется внутренним компонентом.
## 6. Примеры admin API
1) Создать сервис WEB:

View File

@@ -4,8 +4,8 @@ services:
command:
- --configFile=/etc/traefik/traefik.yml
ports:
- "80:80"
- "443:443"
- "127.0.0.1:8288:80"
- "127.0.0.1:2288:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro

107
docs/PROJECT_CONTEXT.md Normal file
View File

@@ -0,0 +1,107 @@
# Project Context: Portal Stand Access
Этот файл нужен как быстрый технический контекст для нового разработчика/оператора.
## 1) Что это за проект
Веб-портал для выдачи пользователям доступа к стендам/сервисам через браузер.
Ключевая идея:
- пользователь выбирает сервис;
- портал открывает сервис в уже прогретом браузерном контейнере (WEB) или в RDP-слоте;
- каждая пользовательская сессия имеет `session_id` (UUID) и свой URL `/s/<session_id>/...`.
## 2) Текущий стек
- API: FastAPI (`app/main.py`)
- БД: PostgreSQL
- Edge/router: Traefik (обязателен для динамических маршрутов runtime-контейнеров)
- Runtime WEB: `portal-kiosk` (Chromium + x11vnc + websockify/noVNC)
- Runtime RDP: `portal-rdp-proxy` (xfreerdp + x11vnc + websockify/noVNC)
## 3) Принятые продуктовые решения
- Режим VNC как отдельный сервис больше не используется (deprecate).
- Основной сценарий для пользователей: WEB и RDP.
- Для WEB используются прогретые per-service пулы (`warm_pool_size` на сервис).
- Для RDP используется универсальный пул слотов (`UNIVERSAL_POOL_SIZE`).
- Сессии пользователя имеют UUID-ссылки (`/s/<uuid>/...`).
## 4) Критичные маршруты
- `/` — выбор сервисов
- `/go/<slug>` — запуск пользовательской сессии
- `/s/<session_id>/` — страница ожидания старта
- `/s/<session_id>/view` — сессионный view для WEB-пула
- `/svc/<slug>/` — роут к warm runtime конкретного сервиса
- `/admin` — админка
## 5) Что важно помнить по инфраструктуре
1. Traefik удалять нельзя.
Причина: динамические контейнеры создают labels во время работы, и именно Traefik маршрутизирует:
- `/s/<session_id>/...`
- `/svc/<slug>/...`
2. При Nginx Proxy Manager (NPM):
- внешний домен -> NPM -> внутренний Traefik.
- в `docker-compose.yml` Traefik опубликован локально:
- `127.0.0.1:2288 -> 443`
- `127.0.0.1:8288 -> 80`
- в NPM обязательна опция `Websockets Support`.
3. Кнопка «Домой» в runtime UI:
- должна возвращать к выбору сервисов портала (`/`), а не вводить URL в удалённом сайте.
## 6) Диагностика типовых проблем
### A) Черный экран в WEB
Проверять:
- что у noVNC корректный WebSocket endpoint (`.../websockify`);
- что сессия active в БД;
- что warm контейнер сервиса running;
- что в NPM включен websocket proxy.
Быстрая проверка:
- логи `portal-warm-<slug>-*`
- логи `portal-api-1`
- содержимое `/opt/portal/index.html` внутри warm-контейнера.
### B) "Соединение со слотом потеряно" в RDP
Обычно не проблема портала, а проблема соединения `xfreerdp` до целевого host:port/cred/sec.
Смотреть `/tmp/session-app.log`/`xfreerdp.log` в `portal-universal-*`.
### C) Изменения не видны сразу
Если менялись runtime-скрипты, старые warm-контейнеры могут держать старую версию.
Нужно пересобрать образ + пересоздать warm-пул.
## 7) Где смотреть код
- Backend и orchestration: `app/main.py`
- Админка/UI: `app/templates/admin.html`, `app/static/style.css`
- Пользовательский дашборд: `app/templates/dashboard.html`
- WEB runtime: `kiosk/entrypoint.sh`, `kiosk/manager.py`
- RDP runtime: `rdp-proxy/entrypoint.sh`
- Оркестрация: `docker-compose.yml`, `traefik/traefik.yml`
## 8) Операционные команды
Сборка runtime-образов:
```bash
docker compose --profile build-only build kiosk-image rdp-proxy-image universal-runtime-image
```
Поднять всё:
```bash
docker compose up -d --build
```
Пересоздать warm-пул (через API startup/ensure) — обычно перезапуск `api` и/или вызов prewarm из админки.
## 9) Что еще можно улучшить
- вынести миграции в Alembic;
- добавить отдельный health dashboard с websocket/rdp метриками;
- централизованный сбор логов и алерты;
- e2e smoke-тесты на сценарии `/go -> /s/<uuid>/view`.