From 1ec7f62a031d900a1b942016789e82d2aa43631c Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sat, 14 Feb 2026 21:56:02 +0300 Subject: [PATCH] CI/CD security, architecture doc, monitoring, security audit - .github/workflows/security.yml: npm audit, pip-audit, gitleaks, dependency-review - .github/workflows/ci.yml: lint required, ENABLE_DEV_AUTH/DEV_TOKEN for tests - .gitleaks.toml: secret scan config and allowlist - docs/ARCHITECTURE.md: high-level design, layers, auth, deployment - docs/ops/MONITORING.md: Prometheus, health, alerting, Grafana - docs/SECURITY_AUDIT.md: audit tools and procedures (ZAP, Bandit, Trivy) - config/prometheus.yml: example scrape config - README: CI/CD and docs links Co-authored-by: Cursor --- .github/workflows/ci.yml | 93 +++++++++++++++++++++ .github/workflows/security.yml | 69 ++++++++++++++++ .gitleaks.toml | 35 ++++++++ README.md | 16 ++++ config/prometheus.yml | 17 ++++ docs/ARCHITECTURE.md | 119 ++++++++++++++++++++++++++ docs/SECURITY_AUDIT.md | 129 +++++++++++++++++++++++++++++ docs/ops/MONITORING.md | 147 +++++++++++++++++++++++++++++++++ 8 files changed, 625 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/security.yml create mode 100644 .gitleaks.toml create mode 100644 config/prometheus.yml create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/SECURITY_AUDIT.md create mode 100644 docs/ops/MONITORING.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fe27d1b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: КЛГ АСУ ТК CI + +on: + push: + branches: [main, develop] + pull_request: + branches: [main] + +jobs: + backend-tests: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:15-alpine + env: + POSTGRES_USER: klg + POSTGRES_PASSWORD: klg + POSTGRES_DB: klg + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install dependencies + run: | + cd backend + pip install -r requirements.txt + pip install pytest pytest-cov openpyxl reportlab + + - name: Run migrations + env: + DATABASE_URL: postgresql://klg:klg@localhost:5432/klg + run: | + for f in backend/migrations/*.sql; do + PGPASSWORD=klg psql -h localhost -U klg -d klg -f "$f" || true + done + + - name: Run tests + env: + DATABASE_URL: postgresql://klg:klg@localhost:5432/klg + ENABLE_DEV_AUTH: "true" + DEV_TOKEN: test + run: | + cd backend + python -m pytest -v --tb=short --junitxml=results.xml + + - name: Upload results + uses: actions/upload-artifact@v4 + if: always() + with: + name: backend-test-results + path: backend/results.xml + + frontend-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install + run: npm ci + + - name: Lint + run: npm run lint + + - name: Build + run: npm run build + + docker-build: + runs-on: ubuntu-latest + needs: [backend-tests, frontend-lint] + if: github.ref == 'refs/heads/main' + steps: + - uses: actions/checkout@v4 + + - name: Build backend image + run: docker build -t klg-backend:latest ./backend + + - name: Build frontend image + run: docker build -t klg-frontend:latest . diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..821dece --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,69 @@ +# Проверки безопасности: зависимости, секреты, статический анализ +name: Security + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + # Еженедельно по понедельникам 06:00 UTC + - cron: '0 6 * * 1' + +jobs: + npm-audit: + name: npm audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + - run: npm ci + - name: Audit production dependencies + run: npm audit --audit-level=high + continue-on-error: true # не ломать пайплайн; отчёт в логах + + pip-audit: + name: pip audit (Python) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install pip-audit + run: pip install pip-audit + - name: Audit backend dependencies + run: | + cd backend + pip-audit -r requirements.txt + continue-on-error: true + + secret-scan: + name: Secret scan (gitleaks) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Run Gitleaks + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} + with: + config-path: .gitleaks.toml + continue-on-error: true + + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + - uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high + continue-on-error: true diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..f541ecb --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,35 @@ +# Gitleaks: правила поиска секретов в репозитории +# https://github.com/gitleaks/gitleaks + +title = "KLG ASUTK - Secret detection" + +[extend] +useDefault = true + +# Дополнительные паттерны под проект +[[rules]] +id = "generic-api-key" +description = "Generic API Key" +regex = '''(?i)(api[_-]?key|apikey|api_key)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{16,}['"]?''' +tags = ["key", "api"] + +[[rules]] +id = "database-url" +description = "Database URL with password" +regex = '''(postgres|mysql|mongodb)(:\/\/|:)['"]?[^'"\s]+:([^'"\s@]+)@''' +tags = ["database"] + +# Исключения: примеры и тестовые значения +[allowlist] +description = "Allowlist for test/example values" +paths = [ + '''\.env\.example''', + '''backend/\.env\.example''', + '''docs/''', + '''\.md$''', +] +regexes = [ + '''(change-me|example|test|dummy|xxx|your[-_]?key)''', + '''postgresql://klg:klg@''', + '''redis://localhost''', +] diff --git a/README.md b/README.md index 64503ce..485f679 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,22 @@ Annex 1, 6, 7, 8, 19 · Doc 9734, 9760, 9859 ### EASA Part-21 · Part-66 · Part-M · Part-CAMO · Part-145 · Part-ARO +## CI/CD + +- **`.github/workflows/ci.yml`** — тесты backend (pytest), lint и сборка frontend, сборка Docker-образов при push в `main`. +- **`.github/workflows/security.yml`** — проверки безопасности: `npm audit`, `pip-audit`, Gitleaks (секреты), Dependency Review в PR; запуск при push/PR в `main` и по расписанию (еженедельно). + +Подробнее: [docs/SECURITY_AUDIT.md](docs/SECURITY_AUDIT.md). + +## Документация + +| Документ | Описание | +|----------|----------| +| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Архитектура системы (слои, потоки данных, безопасность) | +| [docs/ops/MONITORING.md](docs/ops/MONITORING.md) | Мониторинг production (Prometheus, health, алертинг, Grafana) | +| [docs/SECURITY_AUDIT.md](docs/SECURITY_AUDIT.md) | Security-аудит: инструменты и процедуры | +| [docs/SECURITY.md](docs/SECURITY.md) | Правила безопасности и отчёт об уязвимостях | + ## Тесты ```bash diff --git a/config/prometheus.yml b/config/prometheus.yml new file mode 100644 index 0000000..9ed68c2 --- /dev/null +++ b/config/prometheus.yml @@ -0,0 +1,17 @@ +# Пример конфигурации Prometheus для КЛГ АСУ ТК +# Использование: см. docs/ops/MONITORING.md + +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: 'klg-backend' + metrics_path: /api/v1/metrics + static_configs: + - targets: ['localhost:8000'] + scrape_interval: 15s + + - job_name: 'prometheus' + static_configs: + - targets: ['localhost:9090'] diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..68b947b --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,119 @@ +# Архитектура КЛГ АСУ ТК + +Документ описывает архитектуру системы контроля лётной годности для крупного проекта (frontend + backend + инфраструктура). + +--- + +## 1. Высокоуровневая схема + +``` + ┌─────────────────────────────────────────────────────────┐ + │ Пользователи / Браузер │ + └─────────────────────────────┬─────────────────────────────┘ + │ HTTPS + ┌─────────────────────────────▼─────────────────────────────┐ + │ Frontend (Next.js 14) │ + │ · SSR/CSR · PWA · Tailwind · api-client → Backend │ + │ · next-auth / Keycloak OIDC (JWT) │ + └─────────────────────────────┬─────────────────────────────┘ + │ /api/v1/* (proxy или прямой) + ┌─────────────────────────────▼─────────────────────────────┐ + │ Backend (FastAPI) │ + │ · REST API · RBAC · RLS (multi-tenant) · Prometheus │ + └──┬──────────┬──────────┬──────────┬──────────┬────────────┘ + │ │ │ │ │ + ┌─────────────▼──┐ ┌───▼───┐ ┌──▼──┐ ┌────▼────┐ ┌──▼─────────────┐ + │ PostgreSQL │ │ Redis │ │MinIO │ │Keycloak │ │ Внешние (ФГИС, │ + │ (данные, RLS) │ │(кэш) │ │(S3) │ │ (OIDC) │ │ СМЭВ, email) │ + └────────────────┘ └───────┘ └─────┘ └─────────┘ └────────────────┘ +``` + +--- + +## 2. Слои системы + +### 2.1 Frontend + +| Компонент | Технологии | Назначение | +|-----------|------------|------------| +| Фреймворк | Next.js 14, React 18 | SSR, App Router, API routes (proxy) | +| Стили | Tailwind CSS | Единый UI | +| Данные | SWR, единый `lib/api/api-client.ts` | Запросы к Backend с токеном и 401-обработкой | +| Авторизация | next-auth (beta), Keycloak OIDC | JWT в заголовке `Authorization` | +| PWA | Service Worker, manifest | Офлайн-режим, установка на устройство | + +- **Страницы:** дашборд, парк ВС, контроль ЛГ (директивы, SB, ресурсы, компоненты), наряды ТО, дефекты, персонал ПЛГ, чек-листы, риски, регулятор, нормативная база, настройки и др. +- **Прокси:** в dev `next.config.js` переписывает `/api/v1/*` на Backend (`BACKEND_URL`). + +### 2.2 Backend + +| Компонент | Технологии | Назначение | +|-----------|------------|------------| +| API | FastAPI | REST, OpenAPI, зависимости (DB, auth) | +| БД | SQLAlchemy 2, Alembic | Модели, миграции | +| Авторизация | JWT (Keycloak) или DEV-токен | `app.api.deps.get_current_user`, `require_roles` | +| Мультитенантность | PostgreSQL RLS, `set_tenant(db, org_id)` | Изоляция по организации | +| Файлы | MinIO (S3-совместимый) | Вложения, документы | +| Фоновые задачи | APScheduler (risk_scheduler и др.) | Сканирование рисков, уведомления | + +- **Роуты:** разбиты по доменам (aircraft, airworthiness_core, work_orders, defects, personnel_plg, legal, fgis_revs, regulator и т.д.). +- **Единая точка БД:** `get_db` из `app.api.deps` (реэкспорт из `app.db.session`), в тестах переопределяется в conftest. + +### 2.3 Инфраструктура + +| Сервис | Роль | +|--------|------| +| **PostgreSQL** | Основное хранилище, RLS по `app.current_org_id` | +| **Redis** | Кэш, сессии, опционально очереди | +| **MinIO** | Хранилище файлов (S3 API) | +| **Keycloak** | OIDC: выдача JWT, роли, realm `klg` | +| **ФГИС РЭВС** | Внешний API реестра ВС и СЛГ (REST / СМЭВ 3.0) | + +--- + +## 3. Потоки данных + +### 3.1 Авторизация + +1. Пользователь входит через Keycloak (или в dev — токен `DEV_TOKEN`). +2. Frontend сохраняет JWT (sessionStorage / next-auth) и передаёт в заголовке `Authorization: Bearer `. +3. Backend в `get_current_user` проверяет токен (OIDC или dev), извлекает `organization_id` и роли. +4. Для мультитенантности перед запросами к БД вызывается `set_tenant(db, user.organization_id)` (RLS). + +### 3.2 Сквозные сценарии (ЛГ) + +- **ДЛГ (AD)** → создание наряда (WO) → выполнение → CRS → статус «выполнено». +- **Дефект** → WO → устранение → CRS. +- **Ресурс (Life Limit)** → контроль остатка → WO при достижении лимита. +- **Персонал ПЛГ** → scheduler проверяет сроки квалификации → risk alert при просрочке. + +--- + +## 4. Безопасность + +- **Секреты:** не в коде; `.env` в `.gitignore`, шаблоны `.env.example` и `backend/.env.example`. +- **CORS:** только разрешённые домены из `CORS_ORIGINS`. +- **Авторизация:** в production `ENABLE_DEV_AUTH=false`, только OIDC/JWT. +- **RBAC:** роли admin, authority_inspector, operator_manager, operator_user, mro_*; чувствительные эндпоинты через `require_roles`. +- **SQL:** параметризованные запросы (в т.ч. `set_tenant` через `bindparams`), без конкатенации пользовательского ввода. + +--- + +## 5. Развёртывание + +- **Локально:** `docker compose --profile base up -d`, затем backend (uvicorn) и frontend (npm run dev). +- **Production:** `docker compose --profile full` или Kubernetes (Helm chart в `./helm/klg-asutk`). +- **CI/CD:** GitHub Actions — тесты backend, lint и build frontend, сборка образов; отдельный workflow Security (npm audit, pip-audit, gitleaks). + +--- + +## 6. Связанные документы + +- [SECURITY.md](SECURITY.md) — правила безопасности и отчёт об уязвимостях. +- [docs/ops/MONITORING.md](ops/MONITORING.md) — мониторинг и алертинг в production. +- [docs/SECURITY_AUDIT.md](SECURITY_AUDIT.md) — проведение security-аудита и внешние инструменты. +- [ANALYSIS_AND_RECOMMENDATIONS.md](ANALYSIS_AND_RECOMMENDATIONS.md) — анализ и рекомендации по коду. + +--- + +© АО «REFLY» — Разработчик АСУ ТК КЛГ diff --git a/docs/SECURITY_AUDIT.md b/docs/SECURITY_AUDIT.md new file mode 100644 index 0000000..dde913d --- /dev/null +++ b/docs/SECURITY_AUDIT.md @@ -0,0 +1,129 @@ +# Security-аудит: инструменты и процедуры + +Рекомендации по проведению проверок безопасности с помощью внешних и встроенных инструментов. + +--- + +## 1. Инструменты, встроенные в CI + +В репозитории настроен workflow **`.github/workflows/security.yml`**, который запускается при push в `main`, при pull request в `main` и по расписанию (еженедельно). + +### 1.1 npm audit (Frontend) + +- **Что проверяет:** известные уязвимости в зависимостях npm. +- **В CI:** job `npm-audit`, уровень `--audit-level=high`. +- **Локально:** + ```bash + npm audit + npm audit --audit-level=high # только high/critical + npm audit fix # автоматическое обновление, с осторожностью + ``` + +### 1.2 pip-audit (Backend) + +- **Что проверяет:** уязвимости в Python-пакетах (аналог safety). +- **В CI:** job `pip-audit`, зависимости из `backend/requirements.txt`. +- **Локально:** + ```bash + pip install pip-audit + cd backend && pip-audit -r requirements.txt + ``` + +### 1.3 Gitleaks (сканирование секретов) + +- **Что проверяет:** утечка секретов и ключей в коде и истории коммитов. +- **В CI:** job `secret-scan`, конфиг `.gitleaks.toml` (allowlist для примеров и тестов). +- **Локально:** + ```bash + docker run --rm -v "$(pwd):/path" zricethezav/gitleaks:latest detect --source /path + ``` + или установить [gitleaks](https://github.com/gitleaks/gitleaks) и выполнить `gitleaks detect`. + +### 1.4 Dependency Review (Pull Request) + +- При открытии PR запускается **actions/dependency-review-action**: проверка добавленных зависимостей на известные уязвимости. + +--- + +## 2. Дополнительные проверки (вручную или отдельным job) + +### 2.1 OWASP ZAP (базовое сканирование веб-приложения) + +Подходит для проверки фронтенда и API на типовые уязвимости (XSS, инъекции, небезопасные заголовки). + +**Базовый запуск (Docker):** + +```bash +# Запустить приложение (frontend + backend), затем: +docker run -t --rm -v $(pwd):/zap/wrk:rw \ + -u $(id -u):$(id -g) \ + ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \ + -t http://host.docker.internal:3000 \ + -r zap_report.html +``` + +Для API: + +```bash +docker run -t --rm -v $(pwd):/zap/wrk:rw \ + ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \ + -t http://host.docker.internal:8000/docs \ + -r zap_api_report.html +``` + +Результаты в `zap_report.html` / `zap_api_report.html`. Критичные и высокие риски нужно разбирать и устранять. + +### 2.2 SAST (статический анализ кода) + +- **Frontend:** в CI уже используется ESLint (в т.ч. правила безопасности); при необходимости можно добавить `eslint-plugin-security` или SonarQube/SonarCloud. +- **Backend:** можно подключить Bandit (`pip install bandit`, `bandit -r backend/app`) или Semgrep; при необходимости — отдельный job в CI. + +Пример Bandit (локально): + +```bash +pip install bandit +cd backend && bandit -r app -ll +``` + +### 2.3 Контейнеры (образы Docker) + +- Сканирование образов на уязвимости: **Trivy**, **Snyk**, **docker scout**. +- Пример Trivy: + ```bash + docker build -t klg-backend:latest ./backend + trivy image klg-backend:latest + ``` + +--- + +## 3. Регулярность проверок + +| Проверка | Частота | Где | +|----------|---------|-----| +| npm audit, pip-audit, gitleaks | При каждом push/PR в main + еженедельно | GitHub Actions | +| Dependency Review | Каждый PR в main | GitHub Actions | +| OWASP ZAP | Перед релизом или ежеквартально | Вручную / отдельный job | +| SAST (Bandit/Semgrep) | По желанию в CI или перед релизом | Вручную / job | +| Сканирование образов (Trivy) | При сборке образов или перед деплоем | Вручную / job | + +--- + +## 4. Что делать при обнаружении уязвимости + +1. **Критичная/высокая в зависимостях:** обновить пакет до безопасной версии или найти обход (patch/workaround); при необходимости временно задокументировать риск. +2. **Секрет в репозитории:** считать секрет скомпрометированным, сменить его, удалить из истории (git filter-branch / BFG) или использовать allowlist в gitleaks только для нечувствительных примеров. +3. **Уязвимость в коде (ZAP, SAST):** исправить по рекомендациям инструмента и перепроверить. +4. Не создавать публичные issue с детальным описанием уязвимости до её устранения; отчёт направлять ответственным за безопасность (см. [SECURITY.md](SECURITY.md)). + +--- + +## 5. Чек-лист перед релизом + +- [ ] `npm audit` и `pip-audit` без критичных/высоких рисков или риски приняты и задокументированы. +- [ ] Gitleaks не находит новых секретов (с учётом allowlist). +- [ ] Базовое сканирование OWASP ZAP выполнено, критичные находки устранены. +- [ ] Образы Docker отсканированы (Trivy/Snyk), критичные уязвимости устранены или приняты. + +--- + +© АО «REFLY» — Разработчик АСУ ТК КЛГ diff --git a/docs/ops/MONITORING.md b/docs/ops/MONITORING.md new file mode 100644 index 0000000..f29ec11 --- /dev/null +++ b/docs/ops/MONITORING.md @@ -0,0 +1,147 @@ +# Мониторинг production-окружения КЛГ АСУ ТК + +Рекомендации по настройке мониторинга для промышленной эксплуатации. + +--- + +## 1. Метрики Backend (Prometheus) + +Backend отдаёт метрики в формате Prometheus на эндпоинте: + +- **URL:** `GET /api/v1/metrics` +- **Формат:** text/plain (Prometheus exposition format) + +### Метрики + +| Метрика | Тип | Описание | +|---------|-----|----------| +| `klg_http_requests_total` | counter | Число запросов по method и path | +| `klg_http_request_duration_seconds` | counter | Сумма длительности запросов по method и path | +| `klg_http_errors_total` | counter | Ошибки по коду ответа (4xx, 5xx) | + +### Пример конфигурации Prometheus (scrape) + +Добавьте в `prometheus.yml`: + +```yaml +scrape_configs: + - job_name: 'klg-backend' + metrics_path: /api/v1/metrics + static_configs: + - targets: ['backend:8000'] # или host:port вашего backend + scrape_interval: 15s +``` + +В Kubernetes используйте Service и при необходимости аннотации для Prometheus Operator. + +--- + +## 2. Health Check + +Используйте для проверки живости и готовности: + +| Эндпоинт | Назначение | +|----------|------------| +| `GET /api/v1/health` | Общий статус: БД, Redis, risk_scanner, версия | +| `GET /api/v1/health/health/detailed` | Расширенная проверка: диск, память, счётчики данных | + +Использование в Docker/Kubernetes: + +- **livenessProbe:** `GET /api/v1/health` каждые 10–30 с. +- **readinessProbe:** тот же или `/api/v1/health` с проверкой `status == "healthy"` или `"ok"`. + +Пример для Kubernetes: + +```yaml +livenessProbe: + httpGet: + path: /api/v1/health + port: 8000 + initialDelaySeconds: 30 + periodSeconds: 15 +readinessProbe: + httpGet: + path: /api/v1/health + port: 8000 + initialDelaySeconds: 5 + periodSeconds: 10 +``` + +--- + +## 3. Логирование + +- **Backend:** Python `logging`; при деплое направляйте stdout/stderr в централизованную систему (например, Loki, CloudWatch, ELK). +- **Frontend:** ошибки можно отправлять в Sentry (`NEXT_PUBLIC_SENTRY_DSN`). +- Не логировать секреты и персональные данные в открытом виде. + +--- + +## 4. Алертинг (рекомендуемые правила) + +Настройте алерты в Prometheus/Alertmanager или аналоге. + +| Алерт | Условие | Действие | +|-------|---------|----------| +| Backend down | `up{job="klg-backend"} == 0` | Уведомление on-call | +| Высокий % ошибок | `rate(klg_http_errors_total[5m]) / rate(klg_http_requests_total[5m]) > 0.05` | Разбор инцидента | +| Высокая задержка | Например, p99 latency по метрикам (если добавить histogram) | Деградация качества | +| Health degraded | Периодический probe к `/api/v1/health` возвращает `status != healthy` | Проверка БД/Redis | + +--- + +## 5. Grafana (пример дашборда) + +Импортируйте или создайте дашборд с панелями: + +- **Requests:** `sum(rate(klg_http_requests_total[5m])) by (method, path)`. +- **Errors:** `sum(rate(klg_http_errors_total[5m])) by (status)`. +- **Health:** результат последнего запроса к `/api/v1/health` (через Blackbox exporter или скрипт). + +Источник данных — Prometheus, указывающий на scrape целевого backend. + +--- + +## 6. Docker Compose (локальный стек мониторинга) + +Опционально для разработки/стенда можно добавить в `docker-compose`: + +```yaml + prometheus: + image: prom/prometheus:latest + volumes: + - ./config/prometheus.yml:/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + depends_on: + - backend + + grafana: + image: grafana/grafana:latest + environment: + GF_SECURITY_ADMIN_PASSWORD: admin + GF_USERS_ALLOW_SIGN_UP: "false" + ports: + - "3001:3000" + depends_on: + - prometheus +``` + +Создайте `config/prometheus.yml` с job `klg-backend` по образцу из раздела 1. + +--- + +## 7. Чек-лист перед production + +- [ ] Prometheus собирает метрики с `/api/v1/metrics`. +- [ ] Liveness/readiness настроены на `/api/v1/health`. +- [ ] Логи backend и frontend попадают в централизованное хранилище. +- [ ] Настроены алерты на падение сервиса и рост ошибок. +- [ ] Контакты on-call заданы в Alertmanager/канале уведомлений. + +--- + +© АО «REFLY» — Разработчик АСУ ТК КЛГ