docs(apex): document safe operations and replication ownership
This commit is contained in:
1 parent
47c70471e1
commit
582fac434f
5 files changed
+205
-16
No files matched your search
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: Composition replication
|
||||
description: Patterns, ownership, and acceptance requirements for replicated applications.
|
||||
weight: 28
|
||||
---
|
||||
|
||||
Replication belongs to an application deployment across independently owned node
|
||||
repositories. It does not clone a node or turn unrelated compositions into a
|
||||
cluster. Each node pins commons, owns its secrets and storage, and runs APEX
|
||||
commands locally.
|
||||
|
||||
This contract describes design requirements. It does not certify a deployment's
|
||||
availability or provide a shared failover daemon, readiness adapter, or promotion
|
||||
command. Those implementations and their evidence belong to the participating
|
||||
applications and node repositories.
|
||||
|
||||
## Choose a pattern
|
||||
|
||||
| Pattern | Responsibility |
|
||||
|---|---|
|
||||
| Stateless copies | Deploy compatible configuration and route only to ready instances. |
|
||||
| Replicated backends | Use application-supported shared state; each backend owns its consistency and recovery. |
|
||||
| Application-native cluster | Follow the application's membership, replication, election, and recovery procedures. |
|
||||
| Active instance with standby | Transfer state consistently and fence the previous writer before promotion. |
|
||||
| Recovery-only deployment | Restore a verified backup and activate explicitly when live replication is not validated. |
|
||||
|
||||
A composition may combine patterns. Duplicate web instances do not imply that
|
||||
duplicate schedulers or workers are safe. Do not copy live database directories
|
||||
as a generic replication method. Backups remain necessary for corruption,
|
||||
accidental deletion, and total group loss.
|
||||
|
||||
## Record the deployment contract
|
||||
|
||||
Keep the following non-secret information beside each participating composition:
|
||||
|
||||
- Group identity, members, failure domains, desired roles, and compatible versions.
|
||||
- Every mutable state store, its write authority, replication method, and recovery procedure.
|
||||
- Dependencies, private endpoints, required ports, and credentials referenced by location.
|
||||
- Shared versus node-specific configuration and the order of coordinated updates.
|
||||
- Readiness, ingress withdrawal, joining, draining, promotion, rejoining, and full-outage recovery.
|
||||
- Recovery-time targets, possible acknowledged-data loss, and session or revocation behavior.
|
||||
|
||||
Distinct hostnames do not prove independent failure domains. Two application
|
||||
instances depending on one unreplicated backend do not survive loss of that
|
||||
backend. Secrets that must match across replicas stay outside Git; node-specific
|
||||
credentials remain distinct.
|
||||
|
||||
## Network and lifecycle requirements
|
||||
|
||||
Validate the actual protocols over the existing private transport, including
|
||||
peer identity, reconnects, port restrictions, and container-network replacement.
|
||||
Node-local Docker names and bridge addresses do not provide cross-host discovery.
|
||||
Do not introduce another network overlay as a side effect of replication setup.
|
||||
|
||||
Container health alone is insufficient: readiness must reflect required
|
||||
dependencies and write authority. Traffic routing must not promote a database
|
||||
or send application writes to an unpromoted standby. Multiple ingress paths to
|
||||
one backend provide ingress redundancy, not backend replication.
|
||||
|
||||
Initial creation, joining, and ordinary restart are separate operations. An
|
||||
ordinary restart must not replay a seed, create a replacement cluster, discard
|
||||
existing data, or promote a replica. A returning former primary stays fenced
|
||||
until reconciled or reseeded and accepted as a replica. Image rollback does not
|
||||
automatically reverse schema changes.
|
||||
|
||||
## Controlled SSO promotion
|
||||
|
||||
The selected Daedalus–Metis pattern is active/standby with native asynchronous
|
||||
database and session replication over existing Xray transport. Icarus is not a
|
||||
member of this application group. No automatic promotion controller or election
|
||||
service is implied by this pattern.
|
||||
|
||||
Before promotion, positively fence the previous writer. An unreachable SSH or
|
||||
tunnel endpoint is not proof of fencing. Record replication positions, possible
|
||||
lost changes, and the explicit native role changes. Preserve enrolled directory
|
||||
data, account identifiers, groups, and application encryption secrets.
|
||||
|
||||
Recent account changes, sessions, or revocations can be lost with asynchronous
|
||||
replication. Verify login, session reset, and stale-session rejection after
|
||||
promotion; resetting application sessions does not revoke every downstream
|
||||
token. Measure operator-driven recovery time rather than promising automatic
|
||||
failover or zero data loss. Node-specific runbooks own the executable procedure.
|
||||
|
||||
## Acceptance evidence
|
||||
|
||||
For each claimed guarantee, exercise relevant process failures, loss of each
|
||||
location, network partitions, stale members, rejoining, and rolling updates.
|
||||
Observe end-user operations and dependency state. Record recovery time, lost
|
||||
acknowledged data, conflicting writers, session behavior, and manual intervention.
|
||||
Test full-group restoration separately.
|
||||
|
||||
Standalone host enrollment through `ci/scripts/init-node.py` ends before
|
||||
application data migration or replication-group creation. It does not authorize
|
||||
formatting disks or promoting writers during a composition operation.
|
||||
@@ -12,7 +12,8 @@ weight: 24
|
||||
|
||||
| Step | Effect |
|
||||
|---|---|
|
||||
| `configure/base` | Ensures a Debian base: package index update, essential packages (`curl`, `wget`, `git`, `rsyslog`), rsyslog running, `ufw` installed, and the `ufw-docker` helper at `~/.local/bin/ufw-docker`. |
|
||||
| `configure/base` | Installs missing Debian packages after checking that APT's simulation contains no upgrades or removals, ensures rsyslog is running, and verifies the pinned `/usr/local/bin/ufw-docker` before privileged execution. Avoid concurrent package operations. |
|
||||
| `configure/timezone` | Applies `configs/timezone` when present and refreshes active cron after a timezone change. Supports `--dry-run`. |
|
||||
| `configure/ufw` | Applies host rules, injects the managed kernel-rule blocks, applies container rules via `ufw-docker`. Supports `--dry-run`. |
|
||||
| `configure/crowdsec` | Installs CrowdSec if absent, deploys `configs/crowdsec/` to `/etc/crowdsec/`, installs collections, and the firewall bouncer when configured. Supports `--dry-run`. |
|
||||
| `configure/cron` | Renders `configs/cron/crontab` through the template layer and installs it — with preview, empty-render refusal (exit `65`), and rollback on a failed install. Supports `--dry-run`. |
|
||||
@@ -27,10 +28,40 @@ After `configure/ufw`, restart `ufw` deliberately (`sudo systemctl restart ufw`)
|
||||
apex compose up # core first, then services alphabetically
|
||||
apex compose down # reverse order
|
||||
apex compose restart
|
||||
apex compose up --dry-run # print the commands only
|
||||
apex compose --dry-run up # print the commands only
|
||||
apex compose -p apex restart traefik
|
||||
apex compose -p sso up -d
|
||||
```
|
||||
|
||||
Extra arguments pass through to `docker compose` per project. Each project's `.env` and `apex.env` are supplied automatically when present.
|
||||
Put wrapper options (`-p` and `--dry-run`) before the action. Extra arguments pass
|
||||
through to Docker Compose for the selected project. Each project's `.env` and
|
||||
`apex.env` are supplied automatically when present. Positional targeting remains
|
||||
available as `apex compose restart apex traefik` or `apex compose up -d apex`;
|
||||
prefer `-p` when arguments could also name a composition.
|
||||
|
||||
APEX does not unlink Xray sockets during Compose operations. Keep node-owned
|
||||
cleanup in Xray's startup entrypoint; unrelated service restarts and unchanged
|
||||
`up` operations can leave Xray running. When a mount or other container definition
|
||||
changes, use targeted `up -d` to recreate it: `restart` retains the old definition.
|
||||
|
||||
### Direct core Compose commands
|
||||
|
||||
```bash
|
||||
apex env --sync
|
||||
cd compositions/apex
|
||||
docker compose config --quiet
|
||||
docker compose restart traefik
|
||||
```
|
||||
|
||||
Sync preserves existing secret and UID/GID text in `.env` and its tier-storage
|
||||
symlink. A managed block loads committed `apex.env` settings, including profiles,
|
||||
then synthesized node/path values. Writes use mode `0600`. Resync after changing
|
||||
those settings or paths; do not hand-edit the managed block. Docker's shell
|
||||
environment still overrides file values.
|
||||
|
||||
`eval "$(apex env)"`, `apex env --dotenv`, and `apex env --write generated.env`
|
||||
export or save generated APEX values only. They do not load composition secrets
|
||||
or replace the full `--sync` bridge. Output modes are mutually exclusive.
|
||||
|
||||
## Backups {#backups}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: "Every commons action: arguments and behavior."
|
||||
weight: 32
|
||||
---
|
||||
|
||||
The sixteen [commons](/apex/glossary#commons) actions, by group. Arguments are shown as the parser accepts them; optional arguments are bracketed. Exit codes follow the [engine convention](/apex/reference/cli#exit-codes).
|
||||
The [commons](/apex/glossary#commons) actions, by group. Arguments are shown as the parser accepts them; optional arguments are bracketed. Exit codes follow the [engine convention](/apex/reference/cli#exit-codes).
|
||||
|
||||
## configure {#configure}
|
||||
|
||||
@@ -12,13 +12,19 @@ The sixteen [commons](/apex/glossary#commons) actions, by group. Arguments are
|
||||
|
||||
`apex configure [--dry-run]`
|
||||
|
||||
Runs the whole suite in fixed order — `base`, `ufw`, `crowdsec`, `cron`, `systemd`, `routing` — and stops at the first failing step, propagating its exit code. `--dry-run` is forwarded to the steps that support it.
|
||||
Runs the suite in order: `base`, `timezone`, `ufw`, `crowdsec`, `cron`, `systemd`, `routing`, then additional node actions. A failing step contributes a nonzero exit status; later steps may still run. `--dry-run` is forwarded only to steps that support it, so it is not a guarantee that the entire umbrella command is read-only.
|
||||
|
||||
### configure/base
|
||||
|
||||
`apex configure/base`
|
||||
|
||||
Debian-only guard (exit `1` elsewhere). Updates the package index, installs the essential packages (`curl`, `wget`, `git`, `rsyslog`), ensures rsyslog is running, installs `ufw` when absent, and downloads the `ufw-docker` helper to `~/.local/bin/ufw-docker` (skipped when already present).
|
||||
Debian-only guard (exit `1` elsewhere). Checks installed package state for `curl`, `wget`, `git`, `rsyslog`, and `ufw`; installs missing packages and ensures rsyslog is running. Refuses an APT simulation containing upgrades or removals and uses `--no-upgrade --no-remove`. Avoid concurrent package operations: simulation and installation are separate transactions. Verifies the immutable revision and SHA-256 of `/usr/local/bin/ufw-docker` before running it as root. Unsafe paths and unverified downloads are rejected; an executable file alone is not trusted.
|
||||
|
||||
### configure/timezone
|
||||
|
||||
`apex configure/timezone [--dry-run]`
|
||||
|
||||
Applies the IANA zone named in `configs/timezone` and refreshes active cron after a change. An absent declaration preserves the current timezone; an invalid zone fails before changing it.
|
||||
|
||||
### configure/ufw
|
||||
|
||||
@@ -110,9 +116,19 @@ Two passes: (1) [anchor-IP](/apex/glossary#anchor-ip) validation over `compositi
|
||||
|
||||
### compose
|
||||
|
||||
`apex compose <action> [--dry-run] [extra...]`
|
||||
`apex compose [-p <composition>] [--dry-run] <action> [extra...]`
|
||||
|
||||
Orchestrates `docker compose <action>` across the node: the core project first, then services alphabetically (reversed for `down`). `up` implies `-d`; `.env`/`apex.env` are passed per project when present; extra arguments pass through; `--dry-run` (accepted in any position) prints commands instead of executing.
|
||||
Without a target, visits core first and other compositions alphabetically, reversed for `down`. `-p` selects one composition or `all`; `up` defaults to detached mode. `.env` then `apex.env` are passed per project, with generated identity/path values in the process environment. Remaining arguments pass through to Docker Compose. Wrapper options precede the action; `--dry-run` prints commands without executing them.
|
||||
|
||||
Compatibility forms include `apex compose restart apex traefik` and `apex compose up -d apex`. Use explicit `-p` to distinguish a composition from a service or option value. No Compose action removes Xray socket paths; cleanup belongs to the node's Xray startup lifecycle.
|
||||
|
||||
## env {#env}
|
||||
|
||||
`apex env [--export | --dotenv | --write <path> | --sync]`
|
||||
|
||||
Default output is shell-quoted APEX exports for `eval "$(apex env)"`. `--dotenv` emits dotenv syntax; `--write` writes generated values to a separate file, including a relative filename. These modes do not read composition credentials or merge `apex.env`.
|
||||
|
||||
`--sync` preserves existing `compositions/apex/.env` text and updates only its managed block: committed `apex.env` settings first, generated identity/path values last. This includes non-APEX settings such as `COMPOSE_PROFILES` and `TZ`, allowing bare Docker Compose commands in the core directory. Existing tier symlinks remain intact, and synchronized files use mode `0600`. Resync after changing source settings or tier paths. Malformed managed markers fail without rewriting uncertain content. Shell environment values still have Docker Compose precedence.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ weight: 24
|
||||
|
||||
| Шаг | Эффект |
|
||||
|---|---|
|
||||
| `configure/base` | Готовит базовую систему Debian: обновляет списки пакетов, ставит базовые утилиты (`curl`, `wget`, `git`, `rsyslog`), запускает службу rsyslog, устанавливает `ufw` и вспомогательный скрипт `ufw-docker` в `~/.local/bin/ufw-docker`. |
|
||||
| `configure/base` | Устанавливает недостающие пакеты Debian после проверки плана APT на обновления и удаления, запускает rsyslog и проверяет закреплённую версию `/usr/local/bin/ufw-docker` перед запуском от root. Не запускайте другие пакетные операции одновременно. |
|
||||
| `configure/timezone` | Применяет `configs/timezone`, если файл есть, и перезапускает активную службу cron после смены часового пояса. Поддерживает `--dry-run`. |
|
||||
| `configure/ufw` | Применяет правила хоста, настраивает цепочки правил ядра и пробрасывает правила для контейнеров через `ufw-docker`. Поддерживает флаг `--dry-run`. |
|
||||
| `configure/crowdsec` | Устанавливает CrowdSec (если он ещё не поставлен), копирует `configs/crowdsec/` в `/etc/crowdsec/`, ставит коллекции и firewall bouncer (если включён в настройках). Поддерживает флаг `--dry-run`. |
|
||||
| `configure/cron` | Рендерит `configs/cron/crontab` через шаблонизатор и устанавливает расписание. Предусмотрены предпросмотр, аварийная остановка при пустом результате (код выхода 65) и откат при ошибке установки. Поддерживает флаг `--dry-run`. |
|
||||
@@ -27,10 +28,41 @@ weight: 24
|
||||
apex compose up # сначала core, затем сервисы по алфавиту
|
||||
apex compose down # обратный порядок
|
||||
apex compose restart
|
||||
apex compose up --dry-run # только напечатать команды
|
||||
apex compose --dry-run up # только напечатать команды
|
||||
apex compose -p apex restart traefik
|
||||
apex compose -p sso up -d
|
||||
```
|
||||
|
||||
Все дополнительные аргументы движок передаёт напрямую в `docker compose` каждого проекта. Файлы `.env` и `apex.env` проектных каталогов подставляются автоматически при их наличии.
|
||||
Указывайте параметры APEX (`-p` и `--dry-run`) перед действием. Остальные аргументы
|
||||
передаются Docker Compose для выбранного проекта. Файлы `.env` и `apex.env`
|
||||
подключаются автоматически, если существуют. Формы `apex compose restart apex traefik`
|
||||
и `apex compose up -d apex` сохраняются; если имя сервиса или значение параметра
|
||||
совпадает с именем композиции, выбирайте цель через `-p`.
|
||||
|
||||
APEX не удаляет сокеты Xray при операциях Compose. Очистка остаётся
|
||||
в скрипте запуска Xray на узле: перезапуск другого сервиса или повторный `up`
|
||||
могут оставить Xray работающим. После изменения монтирования или конфигурации
|
||||
контейнера используйте `up -d` для нужной композиции; `restart` сохраняет прежнюю
|
||||
конфигурацию контейнера.
|
||||
|
||||
### Прямой запуск Compose для core
|
||||
|
||||
```bash
|
||||
apex env --sync
|
||||
cd compositions/apex
|
||||
docker compose config --quiet
|
||||
docker compose restart traefik
|
||||
```
|
||||
|
||||
Синхронизация сохраняет текст секретов и UID/GID в `.env`, а также ссылку
|
||||
на файл в хранилище tier. Управляемый блок содержит настройки `apex.env`, включая
|
||||
профили, затем вычисленные значения узла и путей. Файл записывается с правами
|
||||
`0600`. Повторите синхронизацию после изменения настроек или путей; не редактируйте
|
||||
управляемый блок вручную. Переменные оболочки сохраняют приоритет Docker Compose.
|
||||
|
||||
`eval "$(apex env)"`, `apex env --dotenv` и `apex env --write generated.env`
|
||||
выводят или записывают только вычисленные значения APEX. Они не загружают секреты
|
||||
композиции и не заменяют `--sync`. Выбирайте один режим вывода за вызов.
|
||||
|
||||
## Резервные копии {#backups}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: "Каждое действие commons: аргументы и по
|
||||
weight: 32
|
||||
---
|
||||
|
||||
Шестнадцать действий [«commons»](/apex/glossary#commons) (общего репозитория), разбитых по группам. Аргументы показаны в том виде, в котором их принимает парсер; необязательные аргументы заключены в квадратные скобки. Коды возврата следуют [соглашению движка](/apex/reference/cli#exit-codes).
|
||||
Действия [commons](/apex/glossary#commons) по группам. Аргументы показаны в том виде, в котором их принимает парсер; необязательные аргументы заключены в квадратные скобки. Коды возврата следуют [соглашению движка](/apex/reference/cli#exit-codes).
|
||||
|
||||
## configure {#configure}
|
||||
|
||||
@@ -12,13 +12,19 @@ weight: 32
|
||||
|
||||
`apex configure [--dry-run]`
|
||||
|
||||
Запускает весь набор в фиксированном порядке (`base`, `ufw`, `crowdsec`, `cron`, `systemd`, `routing`) и останавливается на первом неудачном шаге, возвращая его код возврата. Флаг `--dry-run` передаётся шагам, которые его поддерживают.
|
||||
Запускает `base`, `timezone`, `ufw`, `crowdsec`, `cron`, `systemd`, `routing`, затем дополнительные действия узла. Ошибка шага даёт ненулевой итоговый код; последующие шаги могут продолжить работу. Флаг `--dry-run` передаётся только тем шагам, которые его поддерживают, поэтому не гарантирует отсутствие изменений для всей команды.
|
||||
|
||||
### configure/base
|
||||
|
||||
`apex configure/base`
|
||||
|
||||
Проверяет, что операционная система — Debian (иначе завершается с кодом `1`). Обновляет индекс пакетов, устанавливает необходимые пакеты (`curl`, `wget`, `git`, `rsyslog`), проверяет статус службы `rsyslog`, устанавливает `ufw`, если его нет, и загружает вспомогательную утилиту `ufw-docker` в `~/.local/bin/ufw-docker` (если утилита уже есть, загрузка пропускается).
|
||||
Проверяет, что операционная система — Debian; иначе завершается с кодом `1`. Проверяет состояние пакетов `curl`, `wget`, `git`, `rsyslog` и `ufw`, устанавливает недостающие и запускает rsyslog. Отклоняет план APT с обновлениями или удалениями и использует `--no-upgrade --no-remove`. Не запускайте другие пакетные операции одновременно: проверка плана и установка выполняются отдельно. Перед запуском `/usr/local/bin/ufw-docker` от root проверяет закреплённую ревизию и SHA-256. Небезопасные пути и непроверенные загрузки отклоняются; одних прав на исполнение недостаточно.
|
||||
|
||||
### configure/timezone
|
||||
|
||||
`apex configure/timezone [--dry-run]`
|
||||
|
||||
Применяет часовой пояс IANA из `configs/timezone` и перезапускает активную службу cron после изменения. Если файла нет, сохраняет текущий пояс; неверное имя приводит к ошибке до внесения изменений.
|
||||
|
||||
### configure/ufw
|
||||
|
||||
@@ -110,9 +116,19 @@ weight: 32
|
||||
|
||||
### compose
|
||||
|
||||
`apex compose <action> [--dry-run] [extra...]`
|
||||
`apex compose [-p <composition>] [--dry-run] <action> [extra...]`
|
||||
|
||||
Оркеструет запуск `docker compose <action>` по всему узлу: сначала основной проект, затем сервисы в алфавитном порядке (в обратном — для команды `down`). Команда `up` по умолчанию использует ключ `-d`; файлы `.env` и `apex.env` подключаются для каждого проекта при их наличии; дополнительные аргументы пробрасываются дальше; флаг `--dry-run` (принимается в любой позиции) выводит сформированные команды без их выполнения.
|
||||
Без цели обходит сначала core, затем остальные композиции по алфавиту; для `down` порядок обратный. Параметр `-p` выбирает одну композицию или `all`. Команда `up` по умолчанию добавляет `-d`; файлы `.env` и `apex.env` подключаются в этом порядке, вычисленные значения узла и путей передаются через окружение. Параметры APEX ставятся перед действием, остальные аргументы передаются Docker Compose. Флаг `--dry-run` печатает команды без запуска.
|
||||
|
||||
Сохраняются формы `apex compose restart apex traefik` и `apex compose up -d apex`. Используйте `-p`, чтобы явно отличить композицию от сервиса или значения параметра. Команда не удаляет сокеты Xray: очисткой управляет скрипт запуска Xray на узле.
|
||||
|
||||
## env {#env}
|
||||
|
||||
`apex env [--export | --dotenv | --write <path> | --sync]`
|
||||
|
||||
По умолчанию выводит экспорты APEX для `eval "$(apex env)"` с экранированием оболочки. `--dotenv` выводит формат dotenv; `--write` записывает вычисленные значения в отдельный файл, в том числе по относительному пути. Эти режимы не читают секреты композиции и не объединяют `apex.env`.
|
||||
|
||||
Режим `--sync` сохраняет пользовательский текст `compositions/apex/.env` и обновляет управляемый блок: сначала настройки `apex.env`, затем вычисленные значения. В блок входят `COMPOSE_PROFILES` и `TZ`, поэтому Compose можно запускать напрямую из каталога core. Ссылки tier сохраняются, файл получает права `0600`. Повторяйте синхронизацию после изменения исходных настроек или путей. Некорректные маркеры останавливают запись; переменные оболочки сохраняют приоритет Docker Compose.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user