# Развертывание Документ описывает поддерживаемый путь запуска Crank на сервере. Crank запускает три long-running контейнера за reverse proxy и один обязательный one-shot migration job: - `ui` - `admin-api` - `mcp-server` - `migrate` (завершается до readiness Admin/MCP) Можно использовать внешний PostgreSQL или локальный PostgreSQL из compose-профиля `local-db`. ## Схема ```text reverse proxy / -> ui:3000 /api/admin/ -> admin-api:3001 /mcp/ -> mcp-server:3002 migrate -> PostgreSQL -> exit 0 | +-> admin-api readiness +-> mcp-server readiness admin-api -> Valkey/Redis, опционально mcp-server -> Valkey/Redis, опционально admin-api -> внешний OTLP endpoint, опционально mcp-server -> внешний OTLP endpoint, опционально ``` ## Файлы запуска - `deploy/community/docker-compose.yml` - `deploy/community/.env.example` - `deploy/community/docker-compose.images.yml` - `deploy/community/.env.images.example` ## Порты Порты по умолчанию: - `ui`: `3000` - `admin-api`: `3001` - `mcp-server`: `3002` - optional `valkey`: `6379`, только loopback `CRANK_PUBLISH_BIND` управляет публикацией портов: - `127.0.0.1`, если reverse proxy работает на том же host; - `0.0.0.0`, если reverse proxy работает на другом host. ## Reverse proxy Пример `nginx`: ```nginx server { listen 80; server_name crank.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name crank.example.com; ssl_certificate /etc/letsencrypt/live/crank.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/crank.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://192.168.1.106:3000; } location /api/admin/ { proxy_pass http://192.168.1.106:3001/; } location /mcp/ { proxy_pass http://192.168.1.106:3002/; proxy_buffering off; proxy_request_buffering off; proxy_read_timeout 300s; proxy_send_timeout 300s; } } ``` Замените `192.168.1.106` на адрес deployment host. ## Запуск из исходников Проверка compose-файла: ```bash docker compose \ -f deploy/community/docker-compose.yml \ --env-file deploy/community/.env.example \ config -q ``` Перед обновлением существующей установки выполните preflight и проверенный backup по [migration runbook](migrations.md). Source Compose по умолчанию поднимает локальный PostgreSQL 16. После безопасной последовательности запустите: ```bash docker compose \ -f deploy/community/docker-compose.yml \ --env-file deploy/community/.env.example \ up -d ``` Запуск со встроенным Valkey: ```bash docker compose \ -f deploy/community/docker-compose.yml \ --env-file deploy/community/.env.example \ --profile cache \ up -d ``` Для встроенного Valkey: ```text CRANK_CACHE_BACKEND=valkey CRANK_CACHE_URL=redis://valkey:6379/0 CRANK_CACHE_DEFAULT_TTL_MS=60000 ``` ## Запуск готовых образов ```bash mkdir -p crank cd crank curl -fsSLo docker-compose.yml https://git.itexp.me/bsodfather/crank/raw/branch/main/deploy/community/docker-compose.images.yml curl -fsSLo .env.example https://git.itexp.me/bsodfather/crank/raw/branch/main/deploy/community/.env.images.example cp .env.example .env docker compose --profile local-db up -d ``` Если используется внешний PostgreSQL, заполните `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, сначала выполните preflight и backup по [migration runbook](migrations.md), затем запустите: ```bash docker compose up -d ``` ## Проверка состояния ```bash curl http://127.0.0.1:3001/health curl http://127.0.0.1:3002/health curl http://127.0.0.1:3001/ready curl http://127.0.0.1:3002/ready ``` Ожидаемые ответы: ```json {"service":"admin-api","status":"ok"} {"service":"mcp-server","status":"ok"} ``` UI должен возвращать `200 OK`: ```bash curl -I http://127.0.0.1:3000/ ``` ## Эксплуатация - `/health` проверяет, что процесс жив; `/ready` дополнительно проверяет доступность PostgreSQL и используется Docker Compose. - CD перед каждым обновлением создаёт согласованный комплект в `backups/`: дамп PostgreSQL, том артефактов, окружение, Compose и контрольные суммы. Хранятся последние пять локальных комплектов. - Копируйте комплекты резервных копий на отдельный хост или в объектное хранилище. - Проверенное восстановление выполняется только с явным подтверждением: ```bash CRANK_RESTORE_CONFIRM=restore ./scripts/restore-community.sh /opt/crank /opt/crank/backups/20260721T120000Z ``` - Обновления схемы выполняет только one-shot `crank-migrate apply` под canonical transaction advisory lock. `admin-api` и `mcp-server` выполняют read-only compatibility check и не стартуют до успешного migration job. Canonical sequence фиксируется в `__crank_migrations`, legacy ledgers остаются readable; подробности — в [migrations.md](migrations.md). - Не храните реальные секреты в Git. - CD использует неизменяемые теги коммитов. После schema migration автоматический возврат старых образов запрещён, пока N/N-1 window не квалифицирован Story 7.2: оператор сохраняет backup и выбирает matching forward image либо доказанное восстановление согласованного комплекта. - `CRANK_PUBLISH_BIND=0.0.0.0` нужен только если reverse proxy работает на другом host. - OTLP Collector и хранилище трасс не входят в Community Compose. Для внешнего приёмника задайте `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`; секретные headers передавайте через OpenBao, а не через файлы репозитория. - GlitchTip и другие Sentry-совместимые приёмники также не входят в Community Compose. Для отправки только критических ошибок передайте `CRANK_SENTRY_DSN` через OpenBao; пустое значение отключает канал.