spec: define versioned deployment bundle
Conventional commits / commits (pull_request) Successful in 12s
Specs security / security (pull_request) Successful in 8s
Specs verify / verify (pull_request) Successful in 11s
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 10s
Conventional commits / commits (pull_request) Successful in 12s
Specs security / security (pull_request) Successful in 8s
Specs verify / verify (pull_request) Successful in 11s
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 10s
This commit was merged in pull request #14.
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
## Context
|
||||
|
||||
Согласован отдельный репозиторий `deploy` и команда `./deploy.sh <tag>` по SSH.
|
||||
Тег принадлежит комплекту, а не компоненту; соответствие пары хранится в
|
||||
`release.env`. Решения приняты в обсуждении с владельцем и записаны в ADR 016
|
||||
репозитория docs; эти артефакты готовят реализацию, не подтверждают её выполнение.
|
||||
|
||||
На сервере уже есть Compose project `wealthledger`, SQLite, постоянные ключи
|
||||
и read-only mount `certs/tbank-ca.pem` через `TBANK_CA_CERT_PATH`. Внешний HTTPS
|
||||
и Docker подготовлены. Образы публикуются в Nexus независимыми релизами.
|
||||
`containerized-application-delivery` остаётся отдельным active change;
|
||||
его runtime-контракт используется без редактирования или преждевременного archive.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:** небольшой комплект с воспроизводимой парой образов, одним entrypoint,
|
||||
безопасным обновлением SQLite и понятным восстановлением существующего сервера.
|
||||
|
||||
**Non-Goals:** provisioning, CI/CD автодеплой, новый registry, Kubernetes,
|
||||
Ansible-инфраструктура, blue-green, замена БД, backup daemon, автоматическая
|
||||
ротация копий, собственная система миграций или управление HTTPS.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Комплект и постоянные ресурсы
|
||||
|
||||
Минимальное содержимое `deploy`: `compose.yaml`, `release.env`, `.env.example`,
|
||||
`deploy.sh`, README и одна исполняемая проверка сценариев. Compose использует
|
||||
готовые frontend/backend images, migration запускается из backend image.
|
||||
Production-комплект самодостаточен и не требует соседних checkout.
|
||||
Существующие root Compose-файлы для development не удаляются этим change.
|
||||
|
||||
На сервере checkout располагается отдельно от `data/`, `certs/`, `backups/`
|
||||
и защищённого server env. Например, checkout — `/opt/wealthledger/deploy`,
|
||||
остальное — соседние пути в `/opt/wealthledger`. Существующий data path
|
||||
не переименовывается; пути bind mounts абсолютные. Ключи не генерируются
|
||||
повторно. Root filesystem остаётся read-only, процесс non-root, backend
|
||||
не получает host port; сертификат доверия монтируется read-only без отключения TLS.
|
||||
|
||||
`release.env` содержит только полные versioned image references из Nexus;
|
||||
`latest` исключён. Server env хранит настройки и секреты, но не выбирает пару.
|
||||
Переменные окружения вызывающего shell не должны переопределять выбранные
|
||||
images или Compose project. Env-файлы обрабатываются Compose как данные,
|
||||
не выполняются shell через `source`. Полный config с секретами не печатается.
|
||||
|
||||
### Исполнение выбранной версии
|
||||
|
||||
Entrypoint получает тег только из настроенного доверенного `origin`, разрешает
|
||||
его в commit и использует содержимое этого commit для всей операции, включая
|
||||
версию deploy-логики. Полученный ранее тег не перезаписывается при расхождении.
|
||||
Работа идёт из временного snapshot выбранного commit; запущенный скрипт и
|
||||
операторские изменения checkout не перезаписываются переключением ветки.
|
||||
Compose file, env files и project `wealthledger` задаются явно: временная
|
||||
директория не должна создать второй project или изменить пути данных.
|
||||
|
||||
До остановки выполняются проверки входов, ресурсов, конфигурации и загрузка
|
||||
образов. Поддерживаемый target — один Linux Docker host; Git, Bash и `flock`
|
||||
входят в перечисленные README предпосылки. Архитектура опубликованных образов
|
||||
должна соответствовать серверу; multi-platform поддержку этот change не добавляет.
|
||||
|
||||
### Обновление, повтор и состояние
|
||||
|
||||
Один `flock` на установку исключает конкурирующие запуски. Не добавляется
|
||||
сервис блокировок. Файл блокировки и минимальные служебные записи находятся
|
||||
вне checkout, с ограниченными правами, без секретов.
|
||||
|
||||
Нужны только запись последнего успешного релиза и маркер незавершённого
|
||||
обновления: выбранный commit, фактические images, этап и расположение backup.
|
||||
Маркер сохраняется до первого изменения runtime; успешная запись атомарно
|
||||
обновляется только после готовности затронутых сервисов. При прерывании
|
||||
маркер остаётся для диагностики; новый запуск требует ручного разбора по README.
|
||||
Это не журнал всех deployments и не отдельная база состояний.
|
||||
При первом переходе предыдущая версия описывается фактической парой images:
|
||||
несуществующий тег прежнего комплекта не придумывается.
|
||||
|
||||
План изменений сверяет желаемые images и Compose service configuration
|
||||
с фактическими контейнерами. Для сравнения использовать native Compose
|
||||
service hash и Docker labels, если их соответствие подтверждено проверкой.
|
||||
Секреты не записываются в служебные файлы. Отсутствие достоверного baseline
|
||||
не разрешает frontend-only shortcut: первый переход с серверного Compose
|
||||
выполняется как полное обновление с backup. Успешная запись сама по себе
|
||||
не заменяет проверку фактически работающих контейнеров.
|
||||
|
||||
При обновлении API: stop backend → проверка отсутствия migration writer →
|
||||
новый уникальный каталог backup → копия всего data directory, включая WAL/SHM →
|
||||
одноразовая migration → backend readiness. Для существующей установки отсутствие
|
||||
`wealthledger.db` — ошибка. Только явный первый запуск `--init` на пустом
|
||||
каталоге без прежнего runtime допускает создание новой базы без backup.
|
||||
Копия отмечается пригодной для восстановления только после успешного окончания
|
||||
копирования; незавершённый каталог не выдаётся за готовый backup.
|
||||
|
||||
Неизменный frontend не пересоздаётся; обновление только frontend не запускает
|
||||
зависимости. При обновлении обоих компонентов новый frontend запускается после
|
||||
готовности backend. Healthchecks используются из готовых images через Compose;
|
||||
новый HTTP endpoint не нужен. Browser smoke через HTTPS остаётся отдельной
|
||||
проверкой выпуска: container health не доказывает login/refresh.
|
||||
|
||||
Backup failure и migration failure прекращают последовательность. При провале
|
||||
readiness backend останавливается. Провал frontend не останавливает исправный
|
||||
backend. Любая ошибка оставляет релиз неподтверждённым, текущую БД и backup
|
||||
неизменёнными процедурой восстановления; диагностика не выводит secrets.
|
||||
|
||||
### Выпуск и инструкция
|
||||
|
||||
После публикации компонентов оператор меняет пару в `release.env`, проверяет
|
||||
её на disposable установке и выпускает отдельный неизменяемый `vX.Y.Z` тег
|
||||
`deploy`. Компонентные pipeline не связываются автоматическим publisher.
|
||||
Первый комплект закрепляет реально доступные образы, не демонстрационные версии.
|
||||
README описывает подготовку Docker/Git/registry/HTTPS, разрешения каталогов,
|
||||
сохранение ключей, подключение действующего Compose project, install/update,
|
||||
диагностику незавершённой операции, ручную очистку backups и recovery.
|
||||
|
||||
## UI/UX Applicability and Package
|
||||
|
||||
**Applicability and scope:** `N/A` — браузерный интерфейс и его состояния
|
||||
не меняются; оператор использует терминал и README. Макеты не нужны.
|
||||
|
||||
## Delivery Map
|
||||
|
||||
| Area | Status | Architectural outcome or N/A reason |
|
||||
| --- | --- | --- |
|
||||
| frontend | `N/A` | Готовый image переиспользуется, UI и pipeline не меняются |
|
||||
| backend | `N/A` | Готовые runtime, healthcheck и migrations переиспользуются |
|
||||
| specs | `affected` | Контракт deployment-bundle и план его проверки |
|
||||
| docs | `affected` | ADR 016 и обновлённый эксплуатационный маршрут после реализации |
|
||||
| deploy | `affected` | Самодостаточный комплект, сценарии проверки и README |
|
||||
| root | `affected` | Только навигация README к production-комплекту; development Compose не меняется |
|
||||
|
||||
Уточнение старого шаблона: обязательные четыре области сохранены; добавлен
|
||||
реальный repository owner `deploy`, явно выбранный пользователем, и `root`
|
||||
для необходимой поправки workspace-навигации. В Tasks используются `[deploy]`
|
||||
и `[root]`, а не фиктивный `[backend]` или `[workspace]`.
|
||||
Это локальное расширение перечня owners для данного change; глобальная
|
||||
переработка SDD schema и process specs в scope не входит. Native structural
|
||||
validation не доказывает соответствие этому уточнению или semantic approval.
|
||||
|
||||
## Solution Assessment
|
||||
|
||||
| Вариант | Fit, зрелость и безопасность | Стоимость и ограничения |
|
||||
| --- | --- | --- |
|
||||
| Только Docker Compose | Зрелый runtime, зависимости, healthchecks и выбор images уже покрыты | Не выполняет stop/copy/migrate и не исключает две операторские операции |
|
||||
| Bash + Git + Compose + flock | Native инструменты владеют загрузкой, запуском и блокировкой; shell связывает существующий безопасный порядок | Небольшой branching требует проверок ошибок и прерываний; подходит одному Linux host |
|
||||
| Ansible | Зрелый механизм управления серверами, но backup/migration порядок всё равно надо определить | Добавляет control environment, inventory и роль при уже подготовленном одном сервере |
|
||||
|
||||
Выбран второй вариант. Чистого Compose недостаточно для согласованной копии
|
||||
при остановленной записи; отдельный provisioning stack не соответствует
|
||||
согласованному отсутствию управления серверной инфраструктурой. Новый package
|
||||
manager, framework или сторонняя runtime-зависимость не вводятся.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Краткий простой и единственный writer сохраняются; внешние процессы записи
|
||||
должны быть исключены оператором при подключении существующей установки.
|
||||
- Локальный backup не спасает от потери диска; свободное место и ручная очистка
|
||||
остаются эксплуатационной обязанностью. Ошибка копирования блокирует миграции.
|
||||
- Native hash может измениться между версиями Compose: сомнение приводит
|
||||
к полному безопасному обновлению, а не к пропуску backup.
|
||||
- Прерванная migration требует разбора, а не слепого повторения команды.
|
||||
Ни служебный маркер, ни последний успешный тег не являются копией базы.
|
||||
- Доверие к Git origin и неизменяемым Nexus release tags остаётся существующей
|
||||
границей поставки; собственная система подписей здесь не добавляется.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
Подготовить самодостаточный комплект и проверить безопасный lifecycle на
|
||||
disposable данных. Затем обновить docs, сохранив development-инструкцию.
|
||||
Для действующего сервера сохранить старые настройки и соответствие images,
|
||||
подключить существующие абсолютные пути и project, выполнить первый полный
|
||||
переход с backup. Старый способ запуска не выполнять параллельно.
|
||||
|
||||
### Rollback Contract
|
||||
|
||||
| Field | Decision |
|
||||
| --- | --- |
|
||||
| Status | `required` |
|
||||
| Trigger | Ошибка migration/readiness, прерывание либо выявленная регрессия |
|
||||
| Actions | Остановить API при риске для данных; отдельно выбрать совместимый image либо explicit restore; незавершённый маркер снять только после проверки состояния |
|
||||
| Data safety | Не восстанавливать БД автоматически; перед explicit restore сохранить текущий каталог, выбрать копию, подтвердить потерю новых записей и наличие прежнего ключа |
|
||||
| Verification | На отдельной копии проверить целостность БД, совместимость схемы, auth/cards и расшифровку подключения; после восстановления повторить smoke через HTTPS |
|
||||
Reference in New Issue
Block a user