fix: cyrillic fonts, dev certs, page head, and ru-text typography (#67)

🤖 PR generated for branch `fix/cyrillic-fonts-dev-certs-and-page-head`.

### Changes Summary
- **Fonts**: Add Cyrillic glyph subsets for Lato, EB Garamond, and Fira
Code.
- **Dev**: Support remote Root CA and encrypted dev CA key in
`.env.dev`.
- **UI & Kits**: Add size variant to `Breadcrumbs` component and enlarge
`PageHead` breadcrumbs with tuned collapse scroll threshold.
- **ESLint**: Add `no-hanging-particles` i18n & markdown typography rule
with auto-fixer.
- **Content & i18n**: Apply `ru-text` editorial and typography polish
(em dashes, number ranges, «ё» restoration, non-breaking spaces) across
`services/www` and `services/docs`.
This commit is contained in:
deytenit authored and GitHub committed 2026-10-25 15:21:09 +03:00
1 parent c6487dc258
commit b3638f4d63
111 files changed
+2350 -1512

No files matched your search

@@ -1,25 +1,25 @@
---
title: Эксплуатация узла
description: "Операции day-2: конфигурирование, композиции, резервные копии и синхронизация репозитория."
description: "Операции day-2: конфигурирование, композиции, резервные копии и синхронизация репозитория."
weight: 24
---
**Контекст:** после первоначальной настройки [узел](/apex/glossary#node) управляется исключительно через [движок](/apex/glossary#engine). В этом руководстве описаны регулярные операции и их фактические действия на хосте.
**Контекст:** после первоначальной настройки [узел](/apex/glossary#node) управляется исключительно через [движок](/apex/glossary#engine). В этом руководстве описаны регулярные операции и их фактические действия на хосте.
## Конфигурирование хоста {#configure}
Команда `apex configure` выполняет все шаги настройки в строгой последовательности. Если изменился только один слой, нужный шаг можно вызвать отдельно:
Команда `apex configure` выполняет все шаги настройки в строгой последовательности. Если изменился только один слой, нужный шаг можно вызвать отдельно:
| Шаг | Эффект |
|---|---|
| `configure/base` | Готовит базовую систему Debian: обновляет списки пакетов, ставит базовые утилиты (`curl`, `wget`, `git`, `rsyslog`), запускает службу rsyslog, устанавливает `ufw` и вспомогательный скрипт `ufw-docker` в `~/.local/bin/ufw-docker`. |
| `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`. |
| `configure/systemd` | Рендерит файлы первого уровня из `configs/systemd/` в `/etc/systemd/system/`, перезагружает конфигурацию systemd (daemon-reload) и активирует каждый юнит `.service`. Поддерживает флаг `--dry-run`. |
| `configure/routing` | Включает пересылку IP-пакетов (forwarding), задаёт правило и таблицу маршрутизации (policy-routing) по метке fwmark для границы анклава. Шаг идемпотентен. |
| `configure/base` | Готовит базовую систему Debian: обновляет списки пакетов, ставит базовые утилиты (`curl`, `wget`, `git`, `rsyslog`), запускает службу rsyslog, устанавливает `ufw` и вспомогательный скрипт `ufw-docker` в `~/.local/bin/ufw-docker`. |
| `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`. |
| `configure/systemd` | Рендерит файлы первого уровня из `configs/systemd/` в `/etc/systemd/system/`, перезагружает конфигурацию systemd (daemon-reload) и активирует каждый юнит `.service`. Поддерживает флаг `--dry-run`. |
| `configure/routing` | Включает пересылку IP-пакетов (forwarding), задаёт правило и таблицу маршрутизации (policy-routing) по метке fwmark для границы анклава. Шаг идемпотентен. |
После `configure/ufw` обязательно перезапустите службу: `sudo systemctl restart ufw`. Действие выведет напоминание и проверит, что порт SSH остаётся открытым.
После `configure/ufw` обязательно перезапустите службу: `sudo systemctl restart ufw`. Действие выведет напоминание и проверит, что порт SSH остаётся открытым.
## Жизненный цикл композиции {#compose}
@@ -30,7 +30,7 @@ apex compose restart
apex compose up --dry-run # только напечатать команды
```
Все дополнительные аргументы движок передаёт напрямую в `docker compose` каждого проекта. Файлы `.env` и `apex.env` проектных каталогов подставляются автоматически при их наличии.
Все дополнительные аргументы движок передаёт напрямую в `docker compose` каждого проекта. Файлы `.env` и `apex.env` проектных каталогов подставляются автоматически при их наличии.
## Резервные копии {#backups}
@@ -38,14 +38,14 @@ apex compose up --dry-run # только напечатать команды
apex backup/run "$(cat <path-to-telegram-url-file>)"
```
Команда запускает [resticontainer](https://github.com/deytenit/resticontainer) в&nbsp;режиме one-shot под&nbsp;профилем compose `manual`. Процесс проходит следующие этапы:
Команда запускает [resticontainer](https://github.com/deytenit/resticontainer) в режиме one-shot под профилем compose `manual`. Процесс проходит следующие этапы:
1. Инициализирует репозиторий (если он ещё не&nbsp;создан).
2. Считывает compose-метки `restic.*` (`restic.enable`, `restic.backup.paths` и&nbsp;т.&nbsp;д.), чтобы определить, какие сервисы и&nbsp;пути нужно сохранять.
3. Создаёт единый снимок restic для&nbsp;всех выбранных путей хоста (`--host`&nbsp;= `APEX_NODE_HOST`, `--compression max`).
4. Применяет политику хранения (`forget --prune`) и&nbsp;отправляет уведомление.
1. Инициализирует репозиторий (если он ещё не создан).
2. Считывает compose-метки `restic.*` (`restic.enable`, `restic.backup.paths` и т. д.), чтобы определить, какие сервисы и пути нужно сохранять.
3. Создаёт единый снимок restic для всех выбранных путей хоста (`--host` = `APEX_NODE_HOST`, `--compression max`).
4. Применяет политику хранения (`forget --prune`) и отправляет уведомление.
Если ни&nbsp;один сервис с&nbsp;меткой `restic.*` не&nbsp;сформировал нового снимка, действие завершается с&nbsp;ошибкой. Полный процесс описан в&nbsp;разделе [Concept: Tiered storage](/apex/concepts/tiered-storage#backups). Чтобы резервное копирование и&nbsp;отправка отчётов в&nbsp;Telegram выполнялись автономно, добавьте команду в&nbsp;`configs/cron/crontab`.
Если ни один сервис с меткой `restic.*` не сформировал нового снимка, действие завершается с ошибкой. Полный процесс описан в разделе [Concept: Tiered storage](/apex/concepts/tiered-storage#backups). Чтобы резервное копирование и отправка отчётов в Telegram выполнялись автономно, добавьте команду в `configs/cron/crontab`.
## Синхронизация репозитория (capture-up) {#sync}
@@ -53,9 +53,9 @@ apex backup/run "$(cat <path-to-telegram-url-file>)"
apex sync/repository <telegram-bot-url>
```
Действие фиксирует изменения рабочей копии в&nbsp;ветке `sync/<node>`, выполняет rebase на&nbsp;`origin/main` и&nbsp;отправляет ветку через force-push с&nbsp;lease. Затем CI автоматически вливает изменения обратно в&nbsp;`main`. Этот механизм (capture-up) сохраняет актуальное состояние узла в&nbsp;репозиторий.
Действие фиксирует изменения рабочей копии в ветке `sync/<node>`, выполняет rebase на `origin/main` и отправляет ветку через force-push с lease. Затем CI автоматически вливает изменения обратно в `main`. Этот механизм (capture-up) сохраняет актуальное состояние узла в репозиторий.
Действие прерывается с&nbsp;подробным сообщением, если подмодуль commons содержит незакоммиченные изменения или каталог `compositions/` отсутствует. При&nbsp;конфликтах rebase выполнение останавливается для&nbsp;ручного вмешательства. Подробнее архитектурная модель описана в&nbsp;разделе [Concept: Framework architecture](/apex/concepts/architecture#capture-up).
Действие прерывается с подробным сообщением, если подмодуль commons содержит незакоммиченные изменения или каталог `compositions/` отсутствует. При конфликтах rebase выполнение останавливается для ручного вмешательства. Подробнее архитектурная модель описана в разделе [Concept: Framework architecture](/apex/concepts/architecture#capture-up).
## Мониторинг обновлений {#updates}
@@ -63,7 +63,7 @@ apex sync/repository <telegram-bot-url>
apex sync/packages <telegram-bot-url>
```
Формирует единую сводку в&nbsp;Telegram о&nbsp;доступных обновлениях пакетов apt и&nbsp;устаревших образах контейнеров (локальные дайджесты сравниваются с&nbsp;реестром через `skopeo`). Действие ничего не&nbsp;меняет на&nbsp;хосте&nbsp;— это исключительно плановая проверка.
Формирует единую сводку в Telegram о доступных обновлениях пакетов apt и устаревших образах контейнеров (локальные дайджесты сравниваются с реестром через `skopeo`). Действие ничего не меняет на хосте — это исключительно плановая проверка.
## Извлечение сертификатов {#certs}
@@ -71,11 +71,11 @@ apex sync/packages <telegram-bot-url>
apex utils/extract-traefik-certs <acme.json> <dest-dir> [telegram-bot-url]
```
Экспортирует сертификаты из&nbsp;ACME-хранилища граничного прокси в&nbsp;пары `fullchain.pem` и&nbsp;`privkey.pem` для&nbsp;каждого домена (с&nbsp;помощью утилиты в&nbsp;контейнере). Скрипт ограничивает права доступа к&nbsp;ключам до&nbsp;`600` и&nbsp;передаёт владение файлами запустившему пользователю. Это нужно сервисам, которым требуются исходные PEM-файлы вместо готового TLS-соединения от&nbsp;прокси.
Экспортирует сертификаты из ACME-хранилища граничного прокси в пары `fullchain.pem` и `privkey.pem` для каждого домена (с помощью утилиты в контейнере). Скрипт ограничивает права доступа к ключам до `600` и передаёт владение файлами запустившему пользователю. Это нужно сервисам, которым требуются исходные PEM-файлы вместо готового TLS-соединения от прокси.
---
**См.&nbsp;также:**
**См. также:**
- [Getting started with an apex node](/apex/getting-started)
- [Reference: Actions](/apex/reference/actions)