# Деплой и эксплуатация От «запустил на ноуте» до «живёт на VPS и не стыдно показать security.md». ## Среды ```mermaid flowchart LR Dev[docker-compose.yml] --> St[staging] St --> QA[k6 + ZAP + E2E] QA --> Prod[production] ``` | Среда | Compose | APP_ENV | Docs | Demo users | |-------|---------|---------|------|------------| | Dev | `docker-compose.yml` | development | ✅ | ✅ | | CI/E2E | `docker-compose.test.yml` | test | ✅ | ✅ | | Staging | `infra/docker/docker-compose.staging.yml` | staging | ❌ | ❌ | | Production | `infra/docker/docker-compose.prod.yml` | production | ❌ | ❌ | ## Локальная разработка ```bash # 1. venv + зависимости backend (один раз) python3 -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r apps/api/requirements-dev.txt # 2. Секреты установки (один раз, до первого docker compose up) python apps/api/scripts/bootstrap_install.py # 3. Полный стек в Docker (API + БД + web) docker compose --profile docker-web up -d --build # 4. Проверка curl http://localhost:8000/api/v1/health ``` | Сервис | URL | |--------|-----| | Web | http://localhost:5173 | | API | http://localhost:8000 | | PG/Redis/MinIO на хост | `docker-compose.dev-ports.yml` → 5432, 6379, 9000/9001 | > Bootstrap и локальные тесты (`pytest`, `mypy`) — через активированный `.venv`. Docker API использует свой образ; venv нужен для скриптов и разработки на хосте. **Гибрид** (инфра в Docker, frontend локально): ```bash source .venv/bin/activate docker compose up -d pnpm install pnpm --filter web dev ``` **Install secrets на хост** (DBeaver): Admin → Security → Install Secrets → Reveal DB password. ### Стандартные логины (dev) Создаются при seed на старте API. Пароли по умолчанию — из `apps/api/.env.example` (или дефолты в `config.py`). | Email | Пароль | Env | Роль | Superuser | Куда заходит | |-------|--------|-----|------|:---------:|--------------| | `admin@compton.example` | `Admin1234` | `ADMIN_INITIAL_PASSWORD` | admin | да | `/admin` — Users, Content, Security, Diagnostics, secrets | | `ops@compton.example` | `OpsAdmin1234` | `DEMO_OPS_PASSWORD` | admin | нет | `/admin` — Users, Content, Activity (без Security) | | `user@compton.example` | `User1234` | `DEMO_USER_PASSWORD` | user | — | `/profile` | **CMS-страницы (seed):** `about`, `privacy`, `terms` → `/pages/about` и т.д. > **Staging/production:** `SEED_DEMO_USERS=false` — demo `user@` и `ops@` **не создаются**, только admin + CMS. Пароль admin задаётся через `ADMIN_INITIAL_PASSWORD` **до первого seed**, потом — сменить в UI. ## Staging **Нужно:** VPS, DNS, TLS certs в `infra/docker/certs/`, SMTP. ```bash git clone https://git.groupkomton.ru/Matvey/site.git && cd site python3 apps/api/scripts/bootstrap_install.py cp infra/docker/.env.staging.example infra/docker/.env.staging # правим: домен, CORS, SMTP, ADMIN_INITIAL_PASSWORD ./infra/docker/deploy-staging.sh ``` Проверка: ```bash curl -fsS https://STAGING/api/v1/health curl -fsS -o /dev/null -w "%{http_code}" https://STAGING/api/v1/docs # 404 ./infra/scripts/health-check.sh https://STAGING ``` Nginx: `default.tls.conf` — 80→443, HSTS. ## Production ```bash python3 apps/api/scripts/bootstrap_install.py cp infra/docker/.env.production.example infra/docker/.env.production ./infra/docker/deploy-prod.sh infra/docker/.env.production ``` **Сразу после bootstrap:** 1. Бэкап `install.env` off-server (зашифровать) 2. Сменить пароль admin | Сервис | Host ports | |--------|------------| | nginx | 80, 443 | | api, web, pg, redis, minio | internal only | ```bash ./infra/scripts/smoke-prod.sh https://YOUR_DOMAIN ``` ### Rollback ```bash docker compose -f infra/docker/docker-compose.prod.yml down git checkout PREVIOUS_TAG ./infra/docker/deploy-prod.sh infra/docker/.env.production ``` ## Бэкапы и мониторинг | Что | Команда / как | |-----|---------------| | PostgreSQL | `./infra/scripts/backup-postgres.sh` → `backups/postgres-*.sql.gz` | | install.env | `cp …/install.env backups/install.env.$(date +%F).enc` + gpg | | Uptime | `./infra/scripts/health-check.sh URL` или UptimeRobot на `/api/v1/health` + `/` | | Логи | logrotate для `server.log`, `admin-audit.jsonl` | ## Восстановление секретов `install.env` — единственный источник runtime-секретов. Потеряли — не генерируйте новый вслепую. ### Симптомы - `password authentication failed for user "compton_app"` - bootstrap после того, как Postgres volume уже создан ### Fix (есть бэкап) ```bash docker compose down # восстановить apps/api/data/secrets/install.env docker compose up -d --build ``` ### Fix (нет бэкапа) | Вариант | Данные | |---------|--------| | Reveal из другой среды | сохраняются | | `down -v` + bootstrap (**только dev**) | **удаляются все** | ```bash docker compose --profile docker-web down -v python apps/api/scripts/bootstrap_install.py docker compose --profile docker-web up -d --build ``` ## SMTP Staging/prod: `EMAIL_DELIVERY_MODE=smtp`. Dev: `memory` (письма в RAM, SMTP не нужен). | Env | Назначение | |-----|------------| | `SMTP_HOST`, `SMTP_PORT`, `SMTP_FROM` | сервер | | `FRONTEND_URL` | ссылки в письмах | ## Troubleshooting | Проблема | Решение | |----------|---------| | `install.env missing` | `python apps/api/scripts/bootstrap_install.py` | | `password authentication failed` | [восстановление секретов](#восстановление-секретов) — bootstrap **до** первого `docker compose up` | | `/login`, `/recipes` пустые / 404 после clone | `bash scripts/materialize-wesp-static.sh` (или `pnpm --filter web dev` — predev сам) | | `WESP static not found` в CI/скрипте | обновите repo: `public/wesp/` в git; скрипт materialize не требует соседний `wesp/` | | Login failed | `curl …/health`, проверить `.env`, restart web | | 401 refresh в консоли (гость) | норма на публичных страницах | | Logout после F5 на `/admin` | rebuild web, перелогиниться | | «На сайт» ведёт на login | должно быть `href="/"`, rebuild | | Port 5173 busy | stop Docker web **или** local Vite | | CORS | `VITE_USE_API_PROXY=true`, не бить напрямую :8000 | | Нет Security/Diagnostics | логин `admin@`, не `ops@` | | Docker web: missing modules | `docker compose … up -d --build web` | ## Compose-справочник | Файл | Назначение | |------|------------| | `docker-compose.yml` | dev | | `docker-compose.dev-ports.yml` | порты на хост | | `docker-compose.test.yml` | CI/E2E | | `infra/docker/docker-compose.staging.yml` | staging | | `infra/docker/docker-compose.prod.yml` | production | Deploy: `infra/docker/deploy-staging.sh`, `deploy-prod.sh`.