баг-фикс завершён
This commit is contained in:
@@ -7,16 +7,29 @@
|
||||
```yaml
|
||||
services:
|
||||
backend: # Spring Boot (Java 17), внутренний порт 8080
|
||||
frontend: # Apache httpd, публикует HTTP_PORT (по умолчанию 80)
|
||||
frontend: # Apache httpd, внутренний порт 80
|
||||
db: # PostgreSQL 16.3, внутренний порт 5432
|
||||
```
|
||||
|
||||
### Сеть
|
||||
|
||||
Compose сам создаёт изолированную bridge-сеть `magistr`. Внешняя сеть или отдельно
|
||||
установленный reverse proxy для локального запуска не нужны. Apache раздаёт frontend и
|
||||
проксирует same-origin пути `/api` и `/actuator/health` в backend; backend и PostgreSQL не
|
||||
публикуют порты на хосте.
|
||||
Compose сам создаёт изолированную bridge-сеть `magistr` для приложения и подключает backend
|
||||
с frontend к существующей внешней Docker-сети `proxy`. Caddy из `../сaddy-proxy/` также
|
||||
подключён к `proxy`: на `localhost` он отправляет `/api/*` непосредственно в `backend:8080`,
|
||||
а остальные пути — в `frontend:80`. Контейнеры Magistr не публикуют порты на хосте;
|
||||
PostgreSQL доступен только во внутренней сети `magistr`.
|
||||
|
||||
Перед первым запуском создайте общую сеть и поднимите Caddy:
|
||||
|
||||
```bash
|
||||
docker network inspect proxy >/dev/null 2>&1 || docker network create proxy
|
||||
docker compose -f ../сaddy-proxy/compose.yaml up -d
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Для `https://localhost` Caddy выпускает сертификат своим локальным CA. На CachyOS/Arch
|
||||
корневой сертификат устанавливается в системное хранилище через `trust anchor`; точная
|
||||
команда приведена в `STARTUP_GUIDE.md`.
|
||||
|
||||
Данные PostgreSQL сохраняются в именованном томе `postgres_data`. Обычный
|
||||
`docker compose down` не удаляет их; явный `docker compose down -v` выполняет полный сброс.
|
||||
@@ -39,8 +52,9 @@ LOGIN_RATE_BASE_BLOCK_DURATION=1m
|
||||
LOGIN_RATE_MAX_BLOCK_DURATION=15m
|
||||
LOGIN_AUDIT_RETENTION=90d
|
||||
TRUSTED_PROXY_CIDRS=172.16.0.0/12
|
||||
BUSINESS_TIME_ZONE=Europe/Moscow
|
||||
TZ=Europe/Moscow
|
||||
OTEL_SDK_DISABLED=true
|
||||
HTTP_PORT=80
|
||||
```
|
||||
|
||||
Начальный шаблон находится в `.env.example`: скопируйте его в игнорируемый Git файл `.env`
|
||||
@@ -51,10 +65,15 @@ HTTP_PORT=80
|
||||
согласованным. Все JWT TTL/cleanup-переменные и параметры защиты входа передаются
|
||||
backend-контейнеру явно. `TRUSTED_PROXY_CIDRS` должен содержать только сеть фактического
|
||||
reverse proxy: заголовок `X-Forwarded-For` от остальных источников backend игнорирует.
|
||||
`BUSINESS_TIME_ZONE` задаёт правила календарных бизнес-дат, а `TZ` и
|
||||
`JAVA_TOOL_OPTIONS=-Duser.timezone=...` фиксируют timezone JVM и контейнера. Абсолютные
|
||||
timestamps при этом всегда передаются между Java и PostgreSQL в UTC.
|
||||
Поскольку локальный Compose не запускает OpenTelemetry Collector, SDK по умолчанию отключён;
|
||||
при подключённом Collector задайте `OTEL_SDK_DISABLED=false` и его OTLP endpoint.
|
||||
|
||||
В продакшене секреты задаются через Kubernetes Secret, а не через коммитимые файлы.
|
||||
Kubernetes `app-config` также явно задаёт `BUSINESS_TIME_ZONE=Europe/Moscow`,
|
||||
`TZ=Europe/Moscow` и `JAVA_TOOL_OPTIONS=-Duser.timezone=Europe/Moscow` для backend pod.
|
||||
|
||||
Встроенного JWT fallback в приложении нет. Отсутствующее, короткое или шаблонное значение
|
||||
останавливает запуск; профиль `production` также требует Secure refresh-cookie.
|
||||
@@ -64,10 +83,10 @@ reverse proxy: заголовок `X-Forwarded-For` от остальных ис
|
||||
### Dockerfile (Backend)
|
||||
|
||||
Backend собирается через multi-stage сборку Maven:
|
||||
1. Этап сборки: `maven:3.9-eclipse-temurin-17` → `mvn package`
|
||||
1. Этап сборки: `maven:3.9.9-eclipse-temurin-17@sha256:f58d59b...` → `mvn package`
|
||||
2. OpenTelemetry Java Agent `2.28.1` загружается как фиксированный Maven-артефакт и
|
||||
проверяется по закреплённому SHA-256
|
||||
3. Этап запуска: `eclipse-temurin:17-jre-alpine` → `java -jar app.jar`
|
||||
3. Этап запуска: `eclipse-temurin:17-jre-alpine@sha256:02320dd4...` → `java -jar app.jar`
|
||||
|
||||
### Dockerfile (Frontend)
|
||||
|
||||
@@ -82,7 +101,8 @@ COPY security.conf /usr/local/apache2/conf/extra/magistr-security.conf
|
||||
COPY proxy.conf /usr/local/apache2/conf/extra/magistr-proxy.conf
|
||||
```
|
||||
|
||||
Оба базовых образа зафиксированы tag и manifest digest. Первый этап собирает зафиксированный
|
||||
Все базовые образы backend/frontend и локальный PostgreSQL зафиксированы одновременно точным
|
||||
tag и manifest digest. Первый этап frontend собирает зафиксированный
|
||||
OpenTelemetry bundle; второй раздаёт только runtime-
|
||||
файлы, без `node_modules`, тестов и build-исходников. Apache подключает `mod_headers`,
|
||||
`mod_proxy` и `mod_proxy_http`; proxy сохраняет исходный `Host`, чтобы `localhost` корректно
|
||||
@@ -340,16 +360,26 @@ Deployment-файлов запрещено.
|
||||
Расположение: `.gitea/workflows/docker-build.yaml`
|
||||
|
||||
Основные шаги:
|
||||
1. Backend unit/component tests, frontend static/unit tests, Compose validation и shell-тест
|
||||
immutable rollout/rollback.
|
||||
1. Backend unit/component tests, frontend static/unit tests, Compose validation, shell-тест
|
||||
immutable rollout/rollback и регрессионная проверка закрепления артефактов.
|
||||
2. Только после успешных gates — login, параллельная сборка и push backend/frontend с
|
||||
SHA-tag и release tag без `latest`.
|
||||
3. Build jobs публикуют digest обоих образов; deploy job устанавливает фиксированный
|
||||
`kubectl v1.33.12` после SHA-256 проверки.
|
||||
4. `scripts/deploy-images.sh` принимает только `image@sha256:...`, сохраняет предыдущие
|
||||
SHA-tag и release tag без `latest`. Сторонние Actions закреплены полными commit SHA.
|
||||
3. BuildKit публикует для обоих образов максимальную provenance- и SBOM-attestation. Build
|
||||
jobs также возвращают registry digest каждого образа.
|
||||
4. Отдельный обязательный job сканирует опубликованные digests закреплённым Trivy `0.63.0` и
|
||||
блокирует deploy при исправимых `HIGH`/`CRITICAL` уязвимостях.
|
||||
5. Deploy job устанавливает фиксированный `kubectl v1.33.12` только после SHA-256 проверки.
|
||||
Java Agent также имеет точную версию и checksum.
|
||||
6. `scripts/deploy-images.sh` принимает только `image@sha256:...`, сохраняет предыдущие
|
||||
ссылки, применяет оба digest и ждёт rollout. При отказе автоматически возвращает оба
|
||||
предыдущих образа и повторно проверяет их готовность.
|
||||
5. Workflow-wide concurrency lock не допускает одновременные production deployment.
|
||||
7. Workflow-wide concurrency lock не допускает одновременные production deployment.
|
||||
|
||||
`scripts/check-artifact-pinning.sh` проверяет Dockerfile, Compose, Actions, checksum и CI
|
||||
gates. При передаче `K8S_DIR=../k8s` он дополнительно требует digest у каждого production
|
||||
образа Kubernetes. Внешний `otel-collector.yaml` использует официальный Collector Contrib
|
||||
`0.153.0@sha256:93aad750175cbf1a973ae1c5886c3371f4d800f61be25cdd26870b8441ffe9fa`;
|
||||
версия и manifest digest обновляются только вместе и проверяются до rollout.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user