161 lines
9.6 KiB
Markdown
161 lines
9.6 KiB
Markdown
# Инструкция запуска Magistr
|
||
|
||
Ниже — минимальный порядок действий. Подробности по инфраструктуре и секретам находятся в
|
||
[`docs/INFRASTRUCTURE.md`](docs/INFRASTRUCTURE.md) и
|
||
[`docs/SECURITY_RUNBOOK.md`](docs/SECURITY_RUNBOOK.md).
|
||
|
||
## 1. Локальный запуск
|
||
|
||
Нужны Git, Docker Engine, Docker Compose и запущенный Caddy из `../сaddy-proxy/`.
|
||
|
||
1. В корне проекта создайте локальный файл настроек:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
openssl rand -base64 36 # значение POSTGRES_PASSWORD
|
||
openssl rand -base64 48 # значение JWT_SECRET
|
||
```
|
||
|
||
Вставьте полученные значения в `.env`. Файл `.env` не коммитьте.
|
||
|
||
2. Один раз создайте общую Docker-сеть, затем запустите Caddy и Magistr:
|
||
|
||
```bash
|
||
docker network inspect proxy >/dev/null 2>&1 || docker network create proxy
|
||
docker compose -f ../сaddy-proxy/compose.yaml up -d
|
||
docker compose config --quiet
|
||
docker compose up -d --build
|
||
docker compose ps
|
||
```
|
||
|
||
3. Откройте `https://localhost` (`http://localhost` перенаправит на HTTPS). Проверьте backend
|
||
через Caddy:
|
||
|
||
```bash
|
||
curl -kfsS https://localhost/actuator/health/readiness
|
||
```
|
||
|
||
Если браузер не доверяет локальному сертификату Caddy, на CachyOS/Arch выполните:
|
||
|
||
```bash
|
||
docker cp caddy:/data/caddy/pki/authorities/local/root.crt /tmp/caddy-local-root.crt
|
||
sudo trust anchor --store /tmp/caddy-local-root.crt
|
||
```
|
||
|
||
До установки проверьте SHA-256 отпечаток командой
|
||
`openssl x509 -in /tmp/caddy-local-root.crt -noout -fingerprint -sha256`, затем полностью
|
||
перезапустите браузер.
|
||
|
||
Для первого локального входа: `admin` / `admin`. Эти данные предназначены только для
|
||
разработки.
|
||
|
||
4. Если запуск не удался:
|
||
|
||
```bash
|
||
docker compose logs --tail=200 backend db frontend
|
||
```
|
||
|
||
Полный локальный сброс БД выполняется командой `docker compose down -v`, но она удалит
|
||
все локальные данные. Обычная остановка без удаления данных: `docker compose down`.
|
||
|
||
## 2. Обновление существующего production
|
||
|
||
Простой push в `main` для первого обновления **недостаточен**. Он выполняет проверки,
|
||
собирает и сканирует образы, но job `deploy-to-k8s` запускается только вручную через
|
||
`workflow_dispatch`. Новые файлы `../k8s` CI не применяет. Gitea 1.25 игнорирует
|
||
`environment` и `concurrency`, поэтому они не используются как production-защита.
|
||
|
||
1. Подготовьте секреты по [`docs/SECURITY_RUNBOOK.md`](docs/SECURITY_RUNBOOK.md):
|
||
|
||
- `app-secret`: новый случайный `JWT_SECRET` не короче 32 байт, `POSTGRES_USER`,
|
||
`POSTGRES_PASSWORD`;
|
||
- `tenants-secret`: новый `tenants.json` с актуальными JDBC URL и ротированными паролями;
|
||
- `otel-postgres-secret`: восемь обязательных параметров подключений Collector;
|
||
- `gitea-registry`: доступ K3s к registry.
|
||
|
||
Для `magistr.zuev.company` нужен tenant с `"domain": "magistr"`, для
|
||
`n8n.zuev.company` — `"domain": "n8n"`. Секреты не сохраняйте в Git или CI-логах.
|
||
|
||
2. Выполните локальные проверки, затем отправьте изменения в `main`:
|
||
|
||
```bash
|
||
K8S_DIR=../k8s bash scripts/check-production-secrets.sh
|
||
K8S_DIR=../k8s bash scripts/check-artifact-pinning.sh
|
||
bash scripts/test-deploy-images.sh
|
||
kubectl kustomize ../k8s >/dev/null
|
||
```
|
||
|
||
Дождитесь успешных checks, сборки и Trivy scan. Скопируйте точные backend/frontend
|
||
ссылки вида `image@sha256:...` из CI/registry.
|
||
|
||
3. Объявите техническое окно и временно закройте публичный доступ во внешнем Caddy. Затем
|
||
остановите backend:
|
||
|
||
```bash
|
||
kubectl scale deployment/backend -n magistr --replicas=0
|
||
```
|
||
|
||
Полностью пересоздайте **каждую** PostgreSQL tenant-БД, указанную в новом
|
||
`tenants.json`. Недостаточно удалить `flyway_schema_history` или отдельные таблицы:
|
||
миграции V2–V7 объединены в новую `V1__init.sql`, поэтому старая БД получит checksum
|
||
error, а непустая БД без истории может быть ошибочно принята Flyway за baseline.
|
||
Пользователь БД должен уметь создавать схему, функции, триггеры и расширения
|
||
`pgcrypto`/`btree_gist`.
|
||
|
||
4. С рабочей станции с актуальным каталогом `../k8s` выполните первый rollout вручную:
|
||
|
||
```bash
|
||
export BACKEND_IMAGE_REF='gitea.zuev.company/zuev/magistr-backend@sha256:<digest>'
|
||
export FRONTEND_IMAGE_REF='gitea.zuev.company/zuev/magistr-frontend@sha256:<digest>'
|
||
bash ../k8s/deploy.sh apply
|
||
```
|
||
|
||
Скрипт применит ConfigMap, RBAC, Secret mount, probes, OTel и Ingress, поднимет две
|
||
реплики backend и дождётся Flyway/readiness. CI deploy после push не ожидает
|
||
подтверждения: он будет пропущен. Следующие image-only обновления можно запускать
|
||
вручную кнопкой `Run workflow`.
|
||
|
||
5. Перед открытием публичного доступа проверьте:
|
||
|
||
```bash
|
||
kubectl rollout status deployment/backend -n magistr --timeout=300s
|
||
kubectl rollout status deployment/frontend -n magistr --timeout=120s
|
||
kubectl get pods -n magistr
|
||
kubectl logs -n magistr -l app=backend --tail=200
|
||
curl -fsSI https://magistr.zuev.company/
|
||
```
|
||
|
||
Проверьте в браузере login → reload → refresh → logout для каждого tenant-домена.
|
||
Refresh-cookie должна иметь `HttpOnly`, `Secure`, `SameSite=Lax`, path `/api/auth`;
|
||
access JWT не должен находиться в Local/Session Storage. До снятия технического окна
|
||
смените или отключите все демонстрационные учётные записи из `V1__init.sql`.
|
||
|
||
6. После проверки удалите старый `ConfigMap/tenants-config`, отзовите старые DB/OTel
|
||
пароли и верните обычный доступ через Caddy. В дальнейшем image-only изменения можно
|
||
разворачивать ручным запуском workflow, но любые изменения `../k8s` по-прежнему нужно
|
||
применять отдельно или переносить этот каталог в управляемый CI репозиторий.
|
||
|
||
### Важные ограничения rollback
|
||
|
||
- Смена `JWT_SECRET` и сброс БД завершат все старые пользовательские сессии.
|
||
- Readiness требует доступности и успешной миграции всех tenant-БД; одна старая или
|
||
недоступная БД остановит rollout.
|
||
- Автоматический rollback возвращает только два image reference. Он не откатывает БД,
|
||
Secret, ConfigMap или RBAC; после применения новой V1 безопаснее исправлять проблему
|
||
вперёд либо снова пересоздавать БД под старую версию.
|
||
- CI не запускает Testcontainers integration tests: полный PostgreSQL-прогон нужно
|
||
повторить вручную, если после зафиксированных 300 успешных тестов код ещё менялся.
|
||
- `TRUSTED_PROXY_CIDRS=10.42.0.0/16` соответствует текущей pod-сети K3s. При смене
|
||
cluster CIDR его нужно обновить, иначе rate limit увидит неверные клиентские IP.
|
||
|
||
## 3. Что могу выполнить я
|
||
|
||
По вашей команде я могу подготовить `.env`, запустить и диагностировать локальный Compose,
|
||
проверить/исправить код и манифесты, прогнать тесты и dry-run Kubernetes, а при доступном
|
||
`kubectl` — проверить состояние кластера.
|
||
|
||
Без вас я не могу получить реальные пароли и токены, настроить DNS/сертификаты у внешнего
|
||
провайдера или войти в Gitea/Kubernetes, если доступы не предоставлены. Production deploy,
|
||
ротацию Secret и удаление БД я не выполняю без отдельного явного разрешения: это меняет
|
||
внешнюю систему и может прервать работу либо уничтожить данные.
|