--- title: Композиции и общее ядро description: Ядровая композиция на основе include, профили, сети и наслоение окружения. weight: 15 --- Среда выполнения узла описывается в виде [композиций](/apex/glossary#compositions): по одному docker-compose-проекту на сервис в каталоге `compositions//`, плюс [ядровая композиция](/apex/glossary#core-composition) — граничные и инфраструктурные сервисы, необходимые каждому узлу. Ядро находится в [«commons»](/apex/glossary#commons) и подключается каждым узлом через тонкую обёртку. Благодаря этому его манифест пишется один раз и версионируется вместе с фреймворком. ## Обёртка include {#include} Файл `compositions/apex/docker-compose.yml` каждого узла состоит всего из трёх строк: ```yaml {filename="compositions/apex/docker-compose.yml"} name: apex include: - ../../commons/compositions/apex/docker-compose.yml ``` Общий файл полностью параметризован переменными `${APEX_*}` и не содержит относительных путей хоста: все точки монтирования разрешаются через переменные, экспортируемые [движком](/apex/glossary#engine) при вызове, поэтому один и тот же файл корректно работает на каждом узле. Если узлу требуется изменить ядровой сервис (например, опубликовать дополнительный порт хоста), переопределение накладывается через список путей в директиве `include:` без редактирования общего файла: ```yaml {filename="compositions/apex/docker-compose.yml"} name: apex include: - path: - ../../commons/compositions/apex/docker-compose.yml - ./traefik.override.yml ``` > [!NOTE] > Директива `include:` требует Docker Compose версии v2.20 или новее. ## Ядровые сервисы и профили {#core-services} Ядровая композиция определяет общий набор сервисов флота. Всегда включённые сервисы: - **traefik** — граничный обратный прокси и якорь сети `direct` (всегда занимает `.10` в подсети узла). Он терминирует TLS через DNS-челлендж, обнаруживает бэкенды по docker-меткам и открывает панель управления на FQDN узла, ограничивая доступ списком разрешённых IP-адресов [анклава](/apex/glossary#enclave). - **socket-proxy** — отфильтрованный прокси для docker-сокета: traefik получает состояние контейнеров через него и никогда не обращается к сокету напрямую. Опциональные сервисы управляются compose-профилями, которые узел активирует в переменной `COMPOSE_PROFILES` (задаётся в `apex.env`): | Профиль | Сервис | Роль | |---|---|---| | `xray` | xray | Прокси-шлюз с режимом host-network для анклава. | | `adguard` | adguard | DNS-фильтрация в сетевом пространстве имён traefik; маршрутизируется по пути `/adguard` на FQDN узла. | | `alloy` | alloy | Агент наблюдаемости на каждом узле (Grafana Alloy). Собирает метрики хоста и контейнеров, а также логи systemd journal и контейнеров, после чего **проталкивает** их исходящим потоком в центральные Prometheus и Loki (см. [Концепция: Модель безопасности](/apex/concepts/security-model#observability)). Имя хоста (`hostname`) контейнера совпадает с `APEX_NODE_HOST`, благодаря чему метки `node` и `instance` автоматически проставляются на всех метриках и потоках логов. | | `manual` | resticontainer | Одноразовый контейнер резервного копирования на основе меток (`ghcr.io/deytenit/resticontainer`). Никогда не запускается командой `up`; вызывается действием `backup/run`, которое определяет необходимость бэкапа каждого сервиса по compose-меткам `restic.*`. | ## Сети {#networks} Ядровая композиция создаёт три сети узла, а сервисные композиции подключаются к ним через директиву `external: true`: | Сеть | Тип | Назначение | |---|---|---| | `direct` | bridge, подсеть = `APEX_SUBNET` | Сеть со статическими [якорными IP](/apex/glossary#anchor-ip); якорь каждого проекта удерживает здесь фиксированный адрес (см. [Концепция: Схема адресации флота](/apex/concepts/addressing)). | | `enclave` | bridge, `internal: true` | Бэкенд-сеть обратного прокси: через неё traefik направляет трафик к целевым сервисам. | | `socket` | bridge, `internal: true` | Изолирует трафик между traefik и socket-proxy. | Внутри проекта зависимые контейнеры обычно используют сетевое пространство имён якоря (`network_mode: service:`) вместо прямого подключения к сетям. ## Наслоение окружения {#env-layering} Переменные попадают в композицию из трёх слоёв (в порядке возрастания приоритета): 1. **`.env`** — незакоммиченные секреты, символьная ссылка на хранилище уровня 1 (учётные данные `APEX_RESTIC_*`, токены `APEX_TRAEFIK_*`, блок UID/GID). 2. **`apex.env`** — закоммиченные несекретные параметры (`APEX_TRAEFIK_DIRECT_IP`, `APEX_RESTIC_REPOSITORY`, `COMPOSE_PROFILES`, опциональный `APEX_RESTIC_COMPRESSION`). 3. **Экспорт движка** — переменные идентичности `APEX_*` и пути [уровней](/apex/glossary#tier) из `ctx.vars()`. Они внедряются в окружение процесса действиями оркестрации и потому имеют наивысший приоритет над обоими файлами. Критические переменные снабжены суффиксом `?error` в общем файле: если секрет не задан, загрузка конфигурации композиции завершается явной ошибкой, предотвращая запуск некорректно настроенного контейнера. ## Оркестрация {#orchestration} Команда `apex compose ` управляет всеми композициями на узле: - **Порядок:** сначала ядровой проект (он владеет сетями), затем остальные сервисные композиции по алфавиту; команда `down` выполняет действия в обратном порядке. - **Env-файлы:** для каждого проекта существующие файлы `.env` и `apex.env` передаются через флаг `--env-file`. - **Команда `up`:** по умолчанию подразумевает флаг `-d`; любые дополнительные аргументы передаются напрямую в `docker compose`. - **Флаг `--dry-run`:** выводит каждую команду с её рабочим каталогом без выполнения; поддерживается в любом месте командной строки. --- **См. также:** - [Концепция: Схема адресации флота](/apex/concepts/addressing) - [Руководство: Добавление сервисной композиции](/apex/guides/service-composition) - [Справочник: Переменные окружения](/apex/reference/environment)