diff --git a/README.md b/README.md index a09d485..8ec25ac 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ MCPaaS - это low-code платформа для публикации внеш - `docs/mcp-interface.md` - транспорт и контракт публикации MCP tools. - `docs/testing-strategy.md` - стратегия тестирования до и во время разработки. - `docs/runtime-config.md` - конфигурация окружения, storage и секретов. +- `docs/deployment.md` - контейнерный деплой, reverse proxy и CI/CD. - `docs/rust-design.md` - распределение методов, `impl`, `trait` и service-слоя без god-struct. - `docs/development-rules.md` - правила разработки, TDD-процесс и git workflow. - `docs/rust-code-rules.md` - Rust-specific правила кода, toolchain и linting. diff --git a/docs/architecture.md b/docs/architecture.md index ece87db..1cb14f1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -384,6 +384,17 @@ gRPC target: - import/export конфигураций, - workflow публикации и отображение статуса. +### Deployment layer + +Ответственность: + +- контейнерная упаковка приложений; +- orchestration через `docker-compose`; +- reverse proxy routing; +- healthchecks и delivery pipeline. + +Этот слой не должен влиять на доменную модель и application contracts. + ## 10. Предлагаемая структура репозитория Для реализации рекомендуется workspace-структура: diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..4f20aec --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,217 @@ +# Deployment + +## 1. Назначение документа + +Этот документ фиксирует platform-agnostic модель деплоя проекта. + +Он отвечает на вопросы: + +- какие deployment artifacts должны быть в репозитории; +- как проект должен запускаться в production-like окружении; +- как routing должен работать через reverse proxy; +- что должен делать CD pipeline. + +Документ не привязан к конкретному hypervisor, cloud provider, типу VM или домашней инфраструктуре. + +## 2. Базовая модель деплоя + +Для MVP принимается контейнерная модель: + +- `admin-api`, `mcp-server` и `ui` упаковываются в контейнеры; +- `PostgreSQL` запускается как отдельный контейнер; +- сервисы запускаются через `docker-compose`; +- перед приложением находится reverse proxy; +- CI проверяет качество, CD доставляет и перезапускает сервисы. + +## 3. Что должно быть в репозитории + +В проекте должны существовать: + +- `Dockerfile` для `apps/admin-api`; +- `Dockerfile` для `apps/mcp-server`; +- `Dockerfile` для `apps/ui` или отдельный production build flow для UI; +- `docker-compose.yml`; +- `.env.example`; +- `.github/workflows/ci.yml`; +- `.github/workflows/deploy.yml`; +- примеры reverse proxy конфигураций. + +Рекомендуемое стартовое распределение портов: + +- `ui` -> `3000` +- `admin-api` -> `3001` +- `mcp-server` -> `3002` + +## 4. Production-like runtime состав + +Минимальный набор сервисов: + +- `ui` +- `admin-api` +- `mcp-server` +- `postgres` + +Persistent data: + +- volume для `postgres`; +- volume или bind mount для `artifact storage`. + +## 5. Рекомендуемая routing model + +Под одним доменом: + +- `/` -> `ui` +- `/api/admin/` -> `admin-api` +- `/mcp/` -> `mcp-server` + +Это позволяет: + +- централизовать TLS; +- не плодить поддомены без необходимости; +- держать demo URL простым; +- использовать один reverse proxy для UI, API и MCP. + +## 6. Требования к reverse proxy + +Reverse proxy должен обеспечивать: + +- TLS termination; +- редирект `HTTP -> HTTPS`; +- `X-Forwarded-*` headers; +- отключение buffering для MCP endpoint; +- увеличенные таймауты для долгих runtime-запросов; +- корректную маршрутизацию UI, admin API и MCP. + +Особенно для `mcp-server` важно: + +- `proxy_buffering off`; +- `proxy_request_buffering off`; +- длинный `proxy_read_timeout`. + +## 7. Пример `nginx` + +```nginx +server { + listen 80; + server_name example.com; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl http2; + server_name example.com; + + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; + + client_max_body_size 25m; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + + location / { + proxy_pass http://ui:3000; + } + + location /api/admin/ { + proxy_pass http://admin-api:3001/; + } + + location /mcp/ { + proxy_pass http://mcp-server:3002/; + proxy_buffering off; + proxy_request_buffering off; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + } +} +``` + +## 8. Пример `Traefik` + +```yaml +services: + ui: + labels: + - traefik.enable=true + - traefik.http.routers.ui.rule=Host(`example.com`) && PathPrefix(`/`) + - traefik.http.services.ui.loadbalancer.server.port=3000 + + admin-api: + labels: + - traefik.enable=true + - traefik.http.routers.admin.rule=Host(`example.com`) && PathPrefix(`/api/admin`) + - traefik.http.services.admin.loadbalancer.server.port=3001 + + mcp-server: + labels: + - traefik.enable=true + - traefik.http.routers.mcp.rule=Host(`example.com`) && PathPrefix(`/mcp`) + - traefik.http.services.mcp.loadbalancer.server.port=3002 +``` + +Для production нужно отдельно проверить timeout behavior на MCP маршруте. + +## 9. Требования к `docker-compose` + +`docker-compose.yml` должен: + +- поднимать `postgres`, `admin-api`, `mcp-server`, `ui`; +- использовать env vars вместо hardcoded config; +- иметь persistent storage для БД и artifacts; +- не публиковать внутренние сервисы наружу без необходимости; +- содержать healthchecks. + +## 10. Healthchecks + +Нужны как минимум: + +- `GET /health` для `admin-api` +- `GET /health` для `mcp-server` + +CD не должен считать deployment успешным, пока эти endpoints не начали возвращать `200 OK`. + +## 11. CI и CD + +### 11.1. CI + +CI должен выполнять: + +- `cargo fmt --all --check` +- `cargo check --workspace` +- `cargo clippy --workspace --all-targets --all-features -- -D warnings` +- `cargo test --workspace --all-targets` + +### 11.2. CD + +CD для MVP должен: + +- запускаться только для `main`; +- собирать production artifacts; +- доставлять deployment files на целевой Linux host; +- выполнять controlled restart; +- проверять health endpoints после запуска. + +Минимальный flow: + +1. push в `main` +2. успешный `CI` +3. build images +4. upload env и deployment files +5. `docker compose pull` +6. `docker compose up -d` +7. healthcheck verification + +Для MVP допустим deployment с удаленной сборкой на целевом Linux host через `ssh + rsync + docker compose up -d --build`, если не используется отдельный container registry. + +## 12. Что нельзя забыть + +- TLS и renewal сертификатов; +- backup для `postgres` и artifact storage; +- секреты вне репозитория; +- ограничение доступа к `admin-api`; +- rollback на предыдущий image tag или предыдущую compose revision. diff --git a/docs/implementation-plan.md b/docs/implementation-plan.md index 849f718..c79b863 100644 --- a/docs/implementation-plan.md +++ b/docs/implementation-plan.md @@ -353,7 +353,34 @@ DoD: - publish/reload flow стабилен; - документация по запуску достаточна для повторения демо. -## 14. Приоритеты по реализации +## 14. Этап 12. Deployment и CD + +Цель: + +- сделать повторяемый production-like запуск проекта. + +Фичи: + +- `Dockerfile` для приложений; +- `docker-compose.yml`; +- `.env.example`; +- reverse proxy examples; +- health endpoints; +- CD workflow для `main`. + +Результат: + +- проект можно развернуть на Linux-хосте без ручной сборки бинарей и без ad-hoc shell-скриптов. + +DoD: + +- backend приложения собираются в контейнеры; +- есть production-like compose конфигурация; +- reverse proxy examples задокументированы; +- CI и CD разделены; +- deployment проверяется healthchecks. + +## 15. Приоритеты по реализации Если времени не хватает, сохраняется такой приоритет: @@ -369,7 +396,7 @@ DoD: - диплом должен показать работающую платформу; - лучше один полный вертикальный сценарий, чем три недоделанных адаптера. -## 15. Разбиение по фичам +## 16. Разбиение по фичам Каждый этап желательно бить на маленькие фичи: @@ -386,7 +413,7 @@ DoD: Для каждой такой фичи локальный `DoD` должен быть записан до начала реализации хотя бы в рабочем описании задачи или ветки. -## 16. Практический итог +## 17. Практический итог Правильная последовательность для проекта: diff --git a/docs/runtime-config.md b/docs/runtime-config.md index f03f18f..cd2a83e 100644 --- a/docs/runtime-config.md +++ b/docs/runtime-config.md @@ -63,6 +63,8 @@ var/mcpaas/ - `MCPAAS_MCP_BIND` - `MCPAAS_LOG_LEVEL` - `MCPAAS_SECRET_PROVIDER` +- `MCPAAS_PUBLIC_BASE_URL` +- `MCPAAS_MCP_PUBLIC_URL` Опционально: @@ -108,6 +110,19 @@ Demo/deployment: - локальный или сетевой storage; - включенная auth-защита admin-api; - стабильный `Streamable HTTP` endpoint для MCP. +- containerized runtime через `Docker` и `docker-compose`. + +## 8.1. Delivery artifacts + +Для production-like запуска проект должен поставляться с: + +- `Dockerfile` для backend приложений; +- `docker-compose.yml`; +- `.env.example`; +- healthcheck endpoints; +- reverse proxy configuration examples. + +Подробности вынесены в `docs/deployment.md`. ## 9. Что важно не допустить