fix: PageHead header alignment, analytics proxy, and infra improvements (#64)

🤖 Pull request created from `various-fixes` containing PageHead
breadcrumbs and navigation alignment fixes, Umami analytics proxy, and
infrastructure updates.
This commit is contained in:
deytenit authored and GitHub committed 2026-10-24 16:52:49 +03:00
1 parent ff5a50bad8
commit 9ee672504f
110 files changed
+2649 -1760

No files matched your search

@@ -4,13 +4,13 @@ description: "Подключите новый проект к узлу: якор
weight: 23
---
**Контекст:** проект присоединяется к [узлу](/apex/glossary#node) как один каталог в `compositions/`, содержащий написанный вручную файл compose. Контракт фреймворка для этого файла невелик: статический [якорный IP](/apex/glossary#anchor-ip) в сети `direct`, ссылки на внешние сети по ключу и пути к данным относительно уровней.
**Контекст:** проект подключается к [узлу](/apex/glossary#node) в виде отдельного каталога в `compositions/` со своим compose-файлом. Требования фреймворка к этому файлу минимальны: статический [якорный IP](/apex/glossary#anchor-ip) в сети `direct`, подключение к внешним сетям по имени и пути к данным относительно уровней хранения.
{{% steps %}}
### Выделите якорный адрес
Выберите следующий свободный адрес `.20` или выше в /24 узла и запишите его в `compositions/ADDRESSING.md`. Адреса `.10`–`.19` зарезервированы для [базовой композиции](/apex/glossary#core-composition) (см. [Concept: Fleet addressing scheme](/apex/concepts/addressing)).
Выберите следующий свободный адрес `.20` или выше в подсети узла и зафиксируйте его в `compositions/ADDRESSING.md`. Диапазон `.10`–`.19` зарезервирован для [базовой композиции](/apex/glossary#core-composition) (см. [Concept: Fleet addressing scheme](/apex/concepts/addressing)).
### Напишите файл compose
@@ -52,14 +52,14 @@ networks:
Применяемые соглашения:
- **Один якорь на проект** держит статический `ipv4_address` в `direct`; sidecar-контейнеры разделяют его сетевое пространство имён через `network_mode: service:<anchor>`.
- **На сети ссылаются по ключу** (`direct`, `enclave`, `socket`) с `external: true` — их определения принадлежат базовой композиции.
- **Членство в `enclave` плюс метки traefik** публикуют сервис через граничный прокси; прокси обнаруживает его через socket-прокси, никогда через опубликованные порты.
- **Пути к данным относительны уровням** (`./@tierN/...`) и разрешаются через симлинки, создаваемые `tiers/link`.
- **Резервное копирование включается по выбору через метки `restic.*`.** `apex backup/run` управляет [resticontainer](https://github.com/deytenit/resticontainer), который определяет, что снимать, из меток compose: `restic.enable=true` помечает сервис, `restic.backup.paths=<container-path>` называет монтирования для резервного копирования (resticontainer разрешает их в пути хоста). Сервис без меток `restic.*` просто не резервируется. Резервируйте конфигурацию только там, где данные восстановимы.
- Тройка `${APEX_UID...}` берётся из `.env` проекта, поддерживаемого `tiers/useradd`.
- **Один якорь на&nbsp;проект**: контейнер-якорь получает постоянный `ipv4_address` в&nbsp;сети `direct`, а&nbsp;вспомогательные sidecar-контейнеры используют его сетевой стек через `network_mode: service:<anchor>`.
- **Внешние сети подключаются по&nbsp;имени**: для&nbsp;сетей `direct`, `enclave` и&nbsp;`socket` указывается `external: true`, поскольку они объявляются в&nbsp;базовой композиции.
- **Публикация через `enclave` и&nbsp;метки Traefik**: подключение к&nbsp;сети `enclave` вместе с&nbsp;метками маршрутизации открывает сервис через граничный прокси. Прокси связывается с&nbsp;ним через socket-прокси, без&nbsp;проброса портов наружу.
- **Пути к&nbsp;данным привязаны к&nbsp;уровням**: пути вида `./@tierN/...` разрешаются через символические ссылки, которые создаёт действие `tiers/link`.
- **Резервное копирование настраивается метками `restic.*`**: действие `apex backup/run` запускает утилиту [resticontainer](https://github.com/deytenit/resticontainer). Сервис помечается меткой `restic.enable=true`, а&nbsp;пути монтирования для&nbsp;бэкапа перечисляются в&nbsp;`restic.backup.paths=<container-path>` (resticontainer сопоставляет их с&nbsp;путями на&nbsp;хосте). Сервисы без&nbsp;этих меток игнорируются. Сохраняйте только восстановимые данные и&nbsp;конфигурацию.
- **Идентификаторы UID и&nbsp;GID**: переменные `${APEX_UID...}` берутся из&nbsp;файла `.env` проекта, который формирует действие `tiers/useradd`.
### Обеспечьте хранилище и идентичность
### Настройте хранилище и&nbsp;права доступа
```bash
apex tiers/link <tier1> <tier2> <tier3>
@@ -67,34 +67,34 @@ apex tiers/useradd
apex tiers/chown
```
Повторный запуск тройки идемпотентен; он подхватывает новый проект, создаёт его каталоги уровней и `.env`, обеспечивает его пользователя `noroot-<project>` и применяет матрицу владения.
Повторный запуск этих команд идемпотентен: движок находит новый проект, создаёт для&nbsp;него каталоги хранения и&nbsp;файл `.env`, заводит системного пользователя `noroot-<project>` и&nbsp;выставляет права доступа.
### Линтинг
### Проверьте конфигурацию
```bash
apex utils/lint-docker-compose
```
Проверяет каждый якорный IP (корректность формы, уникальность, нахождение внутри подсети узла) и запускает линтер compose по репозиторию. Pre-commit-хук обеспечивает тот же линтинг для staged-файлов compose.
Действие проверяет корректность, уникальность и&nbsp;принадлежность подсети для&nbsp;каждого якорного IP, после чего запускает проверку compose-файлов по&nbsp;всему репозиторию. Тот&nbsp;же линтинг автоматически выполняется хуком pre-commit для&nbsp;всех подготовленных к&nbsp;коммиту файлов.
### Разверните
### Разверните сервисы
```bash
apex compose up
```
Базовая композиция уже поднята; новый проект стартует в своём алфавитном слоте. Проверьте с помощью `docker ps` и, если сервис проксируется, через его маршрут на границе.
Базовая композиция уже работает, поэтому новый проект запустится в&nbsp;порядке своей очереди по&nbsp;алфавиту. Проверьте статус контейнеров через `docker ps`, а&nbsp;доступность маршрута&nbsp;— через граничный прокси.
{{% /steps %}}
## Заметки
- Внутренние секреты сервиса (например, пароль базы данных) размещаются в собственном `.env` проекта в хранилище уровня 1, рядом с автоматически внедряемым блоком UID.
- Никогда не определяйте `direct`/`enclave`/`socket` внутри файла проекта — второе определение будет конкурировать с базовой композицией за владение сетью.
- Секретные данные проекта (например, пароль к&nbsp;базе данных) хранятся в&nbsp;собственном `.env` на&nbsp;уровне 1&nbsp;(@tier1), рядом с&nbsp;автоматически сгенерированным блоком UID.
- Не&nbsp;объявляйте сети `direct`, `enclave` и&nbsp;`socket` заново внутри файла проекта: дублирование определений приведёт к&nbsp;конфликту с&nbsp;базовой композицией за&nbsp;управление сетью.
---
**См. также:**
**См.&nbsp;также:**
- [Concept: Compositions and the shared core](/apex/concepts/compositions)
- [Concept: Tiered storage and privilege isolation](/apex/concepts/tiered-storage)