82 lines
4.3 KiB
Markdown
82 lines
4.3 KiB
Markdown
# module-10-vm1. Production deployment ВМ1
|
||
|
||
> Канонический исполняемый fresh-VM runbook:
|
||
> [`RUNBOOK.production.ru.md`](../codebase/backend/deployment/RUNBOOK.production.ru.md).
|
||
> Общие security/deployment контракты:
|
||
> [`arch-06-service-hosting-security.md`](../../architectory/arch-06-service-hosting-security.md)
|
||
> и [`arch-10-deployment.md`](../../architectory/arch-10-deployment.md).
|
||
> ВМ2:
|
||
> [`module-10-deployment-vm2.md`](../../VM2_services/documentation/module-10-deployment-vm2.md).
|
||
|
||
## Граница документа
|
||
|
||
Этот модуль фиксирует только связь спецификаций и cutover boundary. Команды
|
||
bootstrap, release activation, secrets, TLS, migrations, systemd, smoke,
|
||
reboot, rollback и DR находятся только в production runbook.
|
||
|
||
Production ВМ1 разворачивается на fresh Ubuntu 24.04. In-place hardening
|
||
legacy single-VM/stub инсталляции запрещён. Legacy
|
||
`deployment/DEPLOYMENT_GUIDE.ru.md`, `RUNBOOK.ru.md` и `RUNBOOK.md` являются
|
||
только указателями.
|
||
|
||
## Host deployment contract
|
||
|
||
- разные Ed25519 keys для `deploy` и break-glass `admin`, не совпадающие с
|
||
root bootstrap key;
|
||
- `deploy` не входит в `docker`, `sudo`, `lxd`, `adm`,
|
||
`systemd-journal`; пишет только в `/var/lib/han-deploy/incoming`;
|
||
- active release, Compose, `.env`, scripts/helpers, units, secret mappings,
|
||
credentials и sudoers принадлежат root;
|
||
- activation проверяет approved SHA-256, project root, absolute/`..` paths,
|
||
symlink/hardlink и executable modes;
|
||
- lifecycle — `han-secrets@production.service` и
|
||
`han-stack@production.service` через exact sudoers;
|
||
- public TLS копируется root hook из `/etc/letsencrypt` в
|
||
`/var/lib/han-chat/public-tls`; nginx не получает дерево Certbot;
|
||
- published Docker ports фильтруются по original destination
|
||
`conntrack --ctorigdstport 80/443`, включая restart/reboot gates.
|
||
|
||
## Cutover ВМ1 → ВМ2
|
||
|
||
ВМ1 владеет public guest/API/auth/SMS/Bitrix local-app ingress `80/443`.
|
||
ВМ2 владеет Message Safety v2 на private HTTPS `:8443` и CRM sync public
|
||
webhooks собственного host. Compose, IAM principal и secret bundle между VM не
|
||
разделяются.
|
||
|
||
До переключения caller на ВМ2:
|
||
|
||
1. ВМ2 закрыла TLS SAN/CA, PG migrations, Safety capabilities, S3 read-only,
|
||
performance, egress и rollback gates своего runbook.
|
||
2. ВМ1 использует
|
||
`MESSAGE_SAFETY_URL=https://<VM2_PRIVATE_DNS>:8443` и root-owned
|
||
`MESSAGE_SAFETY_CA_HOST_PATH`.
|
||
3. Internal CA читается фактическим UID API и не читается посторонним UID.
|
||
4. Service token paired, private route/SG разрешают `8443` только от ВМ1/ops.
|
||
5. Local `message-safety`, Redis DB2, local Safety rules env и stub fallback
|
||
отсутствуют в production Compose/validator.
|
||
6. Caller smoke подтверждает allow/deny/pending/timeout, file flow и
|
||
fail-closed поведение; status `stub` не принимается.
|
||
7. После cutover фиксируются release/image digests, schema/config versions,
|
||
firewall counters, traces и rollback approval.
|
||
|
||
Rollback caller переключает только на предыдущий schema-compatible immutable
|
||
release ВМ1. Уже созданные tasks ВМ2 не down-migrate. Потеря ВМ2 не разрешает
|
||
fail-open или возврат local stub.
|
||
|
||
Bitrix sync cutover выполняется отдельно по runbook ВМ2 после expand migrations
|
||
`han_app` на ВМ1. CRM webhook ВМ2 не маршрутизируется через nginx ВМ1.
|
||
|
||
## Связанные модули
|
||
|
||
- API caller и Safety v2:
|
||
[`module-01-api-backend.md`](module-01-api-backend.md).
|
||
- Public edge:
|
||
[`module-03-nginx-vm1.md`](module-03-nginx-vm1.md).
|
||
- Redis DB0/DB1 и удаление legacy DB2:
|
||
[`module-04-redis-vm1.md`](module-04-redis-vm1.md).
|
||
- Keycloak: [`module-08-keycloak.md`](module-08-keycloak.md).
|
||
- Observability:
|
||
[`module-09-observability-vm1.md`](module-09-observability-vm1.md).
|
||
- SMS cutover:
|
||
[`module-11-idgtl-sms.md`](module-11-idgtl-sms.md).
|