108 lines
5.0 KiB
Markdown
108 lines
5.0 KiB
Markdown
# 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`.
|
||
|