Эксплуатация
Операторские процедуры: регистрация пользователей, восстановление зависших окружений, резервное копирование и восстановление.
Параметры платформы
Параметры задаются в конфигурации NixOS-хоста. Все они переопределяемы; значения по умолчанию рассчитаны на профиль team.
| Параметр | Тип | По умолчанию |
platform.baseDomain | string | "example.com" |
platform.controlHost | string | config.platform.baseDomain |
platform.profile | one of "home", "team", "enterprise" | "team" |
platform.tls.mode | one of "acme", "selfsigned" | if profile == "home" then "selfsigned" else "acme" |
platform.audit.retentionDays | positive integer, meaning >0 | 365 |
platform.envRetention.days | null or (positive integer, meaning >0) | null |
platform.defaultQuota | null or string | null |
platform.diskWatermarkPercent | integer between 1 and 99 (both inclusive) | 85 |
Добавление оператора
Чтобы выдать доступ к платформе, зарегистрируйте SSH-ключ пользователя в реестре и, если нужно, дайте права администратора.
- Добавьте публичный ключ в
platform.sshKeysв конфигурации NixOS-хоста:
platform.sshKeys = {
alice = [ "ssh-ed25519 AAAA..." ];
};- При необходимости дайте права администратора в
platform.operators:
platform.operators = {
alice = { admin = true; };
};- Пересоберите хост:
nixos-rebuild switch --flake .#maximasterПосле этого пользователь может отправлять flake через mev и получать доступ по SSH к окружениям, где он указан в users.
Ротация SSH-ключа
- Обновите ключ в
platform.sshKeys. - Пересоберите хост:
nixos-rebuild switch --flake .#maximaster. - Старый ключ больше не принимается.
Восстановление зависшего окружения
Если окружение не отвечает и не спит:
# Проверить состояние юнита.
systemctl status container@env<id>
# Принудительно остановить.
systemctl stop container@env<id>
# Разбудить вручную через CLI.
mev status <owner/slug>
# Или через активатор, по HTTP-пути.
curl -fsS https://<domain>/Если сборка контейнера зависла или сломалась:
# Посмотреть журнал.
mev logs <owner/slug>
journalctl -u container@env<id> -n 100
# При необходимости удалить и создать заново (данные сохраняются).
mev destroy <owner/slug>
mev push /path/to/flakeФлаг --purge-data при destroy удаляет ZFS-датасет необратимо — применяйте, только если данные действительно не нужны.
Восстановление mev.db из резервной копии
/var/lib/mev/mev.db — хранилище плоскости управления: идентификаторы окружений, членство, аудит. Резервная копия снимается ежедневно таймером mev-backup-db через VACUUM INTO.
Шаги восстановления
# 1. Остановить демон.
systemctl stop mevd.service
# 2. Найти последнюю (или нужную) копию.
ls -lt /var/lib/mev/backup/db/mev-*.db | head -5
# 3. Проверить целостность копии.
sqlite3 /var/lib/mev/backup/db/mev-YYYY-MM-DD-HHmmss.db '.tables'
# Ожидаемый вывод: audit domains envs members schema_versions
# 4. Заменить базу.
cp /var/lib/mev/mev.db /var/lib/mev/mev.db.pre-restore
cp /var/lib/mev/backup/db/mev-YYYY-MM-DD-HHmmss.db /var/lib/mev/mev.db
chown mev:mev /var/lib/mev/mev.db
# 5. Запустить демон.
systemctl start mevd.service
# 6. Проверить список окружений.
mev listПосле восстановления базы pkgs/mev-rs/crates/mev-core/src/publish.rs заново соберёт реестр пробуждения, таблицу маршрутов и фрагменты Traefik при следующем mev push (согласование на хосте выполняет mevd-apply). Окружения, созданные или изменённые между снимком и потерей, нужно отправить заново.
Восстановление данных окружений из ZFS
rpool/environments содержит датасеты окружений (rpool/environments/env<id>) с данными приложений и age-ключами секретов.
2a. Откат к локальному снимку
# 1. Посмотреть запущенные окружения.
mev list
# 2. Остановить каждое работающее окружение.
# systemctl stop container@env<id>
# 3. Откатить датасет.
zfs rollback -r rpool/environments@mev-YYYY-MM-DD-HHmmss
# 4. Проверить состояние.
mev status <owner/slug>Флаг -r уничтожает снимки новее целевого. Если текущее состояние ещё может понадобиться, сделайте его снимок перед откатом.
2b. Получить снимок с резервного хоста
# На хосте-источнике или локально:
zfs list -t snapshot backup-pool/environments
# Передать на хост восстановления.
ssh user@backup-host \
"zfs send backup-pool/environments@mev-YYYY-MM-DD-HHmmss" \
| zfs receive -F rpool/environments
# Или инкрементально от общей базы:
ssh user@backup-host \
"zfs send -I backup-pool/environments@base backup-pool/environments@target" \
| zfs receive -F rpool/environments2c. Восстановить одно окружение
# Клонировать датасет окружения из снимка.
zfs clone rpool/environments@mev-YYYY-MM-DD-HHmmss/env<id> \
rpool/environments/env<id>-restore
# Смонтировать и проверить или продвинуть и переименовать.
zfs promote rpool/environments/env<id>-restoreПолное восстановление на чистом хосте
# 1. Установить NixOS (disko + nixos-anywhere или nixos-install).
# 2. Получить датасет окружений с резервного хоста.
ssh user@backup-host \
"zfs send rpool/environments@mev-YYYY-MM-DD-HHmmss" \
| zfs receive -F rpool/environments
# 3. Восстановить mev.db.
cp /path/to/mev-YYYY-MM-DD-HHmmss.db /var/lib/mev/mev.db
chown mev:mev /var/lib/mev/mev.db
# 4. Активировать систему.
nixos-rebuild switch --flake .#maximaster
# 5. Проверить список окружений.
mev list
# 6. Проверить секреты на тестовом окружении.
mev push path/to/test-env-flake
mev status <owner/slug>После первого mev push pkgs/mev-rs/crates/mev-core/src/publish.rs сам восстановит реестр пробуждения, таблицу маршрутов и фрагменты Traefik из хранилища.
Управление резервным копированием
# Проверить последний запуск.
systemctl status mev-backup-db.service
journalctl -u mev-backup-db.service -n 50
# Запустить копирование вручную.
systemctl start mev-backup-db.service
# Список доступных копий SQLite.
ls -lh /var/lib/mev/backup/db/
# Список снимков ZFS.
zfs list -t snapshot -o name,creation rpool/environmentsХранение журнала аудита
Журнал аудита (таблица audit в mev.db) только дополняется. Строки старше platform.audit.retentionDays (по умолчанию 365) ежедневно удаляет таймер mev-audit-prune — это mevd audit-prune, запущенный от пользователя mev. Обычный таймер systemd, а не cron внутри базы: systemd (PID 1) всегда активен, а плоскость управления вызывается через forced-command и не держит постоянный воркер (см. honker-eventbus.md).
# Проверить последний запуск очистки.
systemctl status mev-audit-prune.service
journalctl -u mev-audit-prune.service -n 50
# Запустить очистку вручную.
systemctl start mev-audit-prune.serviceХранение окружений
Окружение, не использованное дольше platform.envRetention.days, сносится автоматически вместе с томом данных. Активность — это lastSeen активатора (запросы через Traefik и открытые SSH-сессии); окружение, которое ни разу не будили, отсчитывается от времени создания. По умолчанию параметр null: автоматический снос выключен, включите его на хосте, где окружения — расходуемый ресурс.
Ежедневный таймер mev-retention запускает mevd retention от пользователя mev — локальное обслуживание без прав оператора (как audit-prune), каждый снос пишется в аудит под служебным оператором retention с флагом purge. Метки времени, которые не удалось разобрать, считаются свежими: битый store или state.json активатора не может привести к удалению данных.
# Показать кандидатов, ничего не удаляя.
sudo -u mev /run/current-system/sw/bin/mevd retention --dry-run
# Последний запуск и журнал.
systemctl status mev-retention.service
journalctl -u mev-retention.service -n 50
# Запустить немедленно.
systemctl start mev-retention.service