Files
Stend_mont/docs/PROJECT_CONTEXT.md
T

11 KiB
Raw Blame History

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 используется общий пул portal-webpool-* (и авторасширение при нагрузке).
  • Для RDP используется универсальный пул слотов (UNIVERSAL_POOL_SIZE).
  • Сессии пользователя имеют UUID-ссылки (/s/<uuid>/...).

4) Критичные маршруты

  • / — выбор сервисов
  • /go/<slug> — запуск пользовательской сессии
  • /s/<session_id>/ — страница ожидания старта
  • /s/<session_id>/view — сессионный view для WEB-пула
  • /svc/<slug>/ — роут к warm runtime конкретного сервиса
  • /w/<slot>/ — роут к WEB pool слоту
  • /u/<slot>/ — роут к universal pool слоту
  • /admin — админка

5) Что важно помнить по инфраструктуре

  1. Traefik удалять нельзя. Причина: динамические контейнеры создают labels во время работы, и именно Traefik маршрутизирует:
  • /s/<session_id>/...
  • /svc/<slug>/...
  • /w/<slot>/...
  • /u/<slot>/...
  1. При Nginx Proxy Manager (NPM):
  • внешний домен -> NPM -> внутренний Traefik.
  • в docker-compose.yml Traefik опубликован так:
    • 0.0.0.0:2288 -> 443
    • 0.0.0.0:8288 -> 80
  • в NPM обязательна опция Websockets Support.
  1. Кнопка «Домой» в runtime UI:
  • должна возвращать к выбору сервисов портала (/), а не вводить URL в удалённом сайте.

6) Диагностика типовых проблем

A) Черный экран в WEB

Проверять:

  • что у noVNC корректный WebSocket endpoint (.../websockify);
  • что сессия active в БД;
  • что контейнер WEB-пула running;
  • что в NPM включен websocket proxy.

Быстрая проверка:

  • логи portal-webpool-*
  • логи portal-api-1
  • содержимое /opt/portal/index.html внутри runtime-контейнера.

B) "Соединение со слотом потеряно" в RDP

Обычно не проблема портала, а проблема соединения xfreerdp до целевого host:port/cred/sec. Смотреть /tmp/session-app.log/xfreerdp.log в portal-universal-*.

C) Изменения не видны сразу

Если менялись runtime-скрипты, старые warm/pool контейнеры могут держать старую версию. Нужно пересобрать образ + пересоздать пул.

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
  • Universal runtime: universal-runtime/entrypoint.sh, universal-runtime/manager.py
  • Оркестрация: docker-compose.yml, traefik/traefik.yml

8) Операционные команды

Сборка runtime-образов:

docker compose --profile build-only build kiosk-image rdp-proxy-image universal-runtime-image

Поднять всё:

docker compose up -d --build

Перезапуск только API:

docker compose up -d api

Проверка состояния:

docker compose ps
docker compose logs -f api traefik

9) Что еще можно улучшить

  • вынести миграции в Alembic;
  • добавить отдельный health dashboard с websocket/rdp метриками;
  • централизованный сбор логов и алерты;
  • e2e smoke-тесты на сценарии /go -> /s/<uuid>/view.

10) Сервер и рабочие пути

  • SSH сервер: ruslan@10.17.39.3
  • Пароль sudo на сервере: utOgbZ09ruslanstand
  • Рабочий каталог проекта на сервере: /root/Stend_mont
  • Файл контекста на сервере: /root/Stend_mont/docs/PROJECT_CONTEXT.md

Базовый рабочий сценарий:

ssh ruslan@10.17.39.3
sudo -s
cd /root/Stend_mont

11) Git доступ и публикация

Репозиторий:

  • https://git.ruslan.xyz/ruslan/Stend_mont

Учетные данные HTTPS (текущие):

  • login: ruslan@ipcom.su
  • password/token: utOgbZ09ruslan

Пример push:

cd /root/Stend_mont
git add .
git commit -m "your message"
git push https://ruslan%40ipcom.su:utOgbZ09ruslan@git.ruslan.xyz/ruslan/Stend_mont main

12) Текущее runtime-состояние (на момент фиксации)

  • API запущен с uvicorn --workers 4 через docker-compose.yml.
  • Для WEB используется portal-webpool-*.
  • Для RDP используется portal-universal-*.

13) Последние изменения (2026-04-21)

  1. UI/брендинг:
  • Тексты в интерфейсе переведены на формулировку инфрастуктурный полигон.
  • На главной панели приветствие в блоке admin-intro: Добро пожаловать в инфрастуктурный полигон.
  • Кнопка выхода на дашборде: Выход (вместо Logout).
  1. WEB runtime (браузерные сервисы):
  • В панели управления runtime оставлены 2 кнопки:
    • Назад
    • Главная (ведет на главную панель портала /).
  • Кнопка Вперед удалена.
  • Изменения применены в kiosk/entrypoint.sh и universal-runtime/entrypoint.sh.
  1. Логин и просроченные пользователи:
  • Если пользователь найден и пароль верный, но аккаунт просрочен/неактивен, на экране входа показывается сообщение: Доступ к сервису приостоновлен, обратитесь к вашему менеджеру.
  • Сообщение рендерится в шаблоне app/templates/login.html через login_error.
  1. Категории сервисов:
  • Добавлены сущности и связи:
    • categories
    • service_categories
  • Категории можно создавать/удалять в админке.
  • При создании/редактировании WEB/RDP сервиса можно выбрать категории.
  • На главной панели добавлен стильный фильтр по категориям (chips) и бейджи категорий на карточке сервиса.
  1. Иконки сервисов:
  • Иконки на главной панели увеличены примерно в 6 раз.
  • Масштабирование иконок: object-fit: contain, чтобы картинка полностью влезала в рамку.
  • В админке загрузка иконки стала автоматической при выборе файла (без кнопки Upload).
  1. Многоворкерный API и startup:
  • API работает с uvicorn --workers 4.
  • Чтобы убрать гонку DDL на старте (при нескольких воркерах), добавлен file-lock на bootstrap схемы:
    • lock-файл: /tmp/portal-schema.lock
    • сериализуется выполнение Base.metadata.create_all(...) и ensure_schema_compatibility().
  1. Операционные заметки по применению runtime-изменений:
  • После изменения kiosk/universal-runtime нужно:
    1. пересобрать runtime-образы,
    2. пересоздать portal-webpool-*, portal-universal-*, portal-warm-* контейнеры,
    3. перезапустить api.

14) Обновление контекста (2026-04-21, вечер)

  1. Главная страница и 500:
  • Был зафиксирован Internal Server Error на /.
  • Причина: синтаксическая ошибка Jinja в app/templates/login.html (поврежденный endif).
  • Статус: исправлено, API перезапущен, / отвечает 200.
  1. Фон и визуальные эффекты:
  • Были тесты фонов main.jpg, main_general.jpg, 123.jpg и локального файла 71ba42f1d7d61e4313ad8fd086d3ed7f.jpg.
  • Текущее состояние по запросу: эффекты отключены.
  • Отключено: parallax, анимации облаков, hover-движения карточек/ссылок, blur карточек.
  • Главная панель оставлена со статичным светлым фоном без motion-эффектов.
  1. Файлы, затронутые в этой волне:
  • app/templates/dashboard.html: удален parallax/cloud слой из разметки.
  • app/static/style.css: добавлен override-блок для отключения эффектов.
  • app/templates/login.html: исправлена ошибка шаблона.
  1. Актуальный операционный контур:
  • Сервер: ruslan@10.17.39.3
  • Проект: /root/Stend_mont
  • Контекст: /root/Stend_mont/docs/PROJECT_CONTEXT.md
  • Применение UI-правок:
    1. ssh ruslan@10.17.39.3
    2. sudo -s
    3. cd /root/Stend_mont
    4. docker compose up -d --build api
  1. Git публикация: