Files
site/docs/deploy.md
T

199 lines
7.5 KiB
Markdown

# Деплой и эксплуатация
От «запустил на ноуте» до «живёт на 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`.