UNRUIN
документация · v1.0

Что это

Что изменилось в 2026-07

Что убрала июльская чистка, почему, и как переписать конфигурацию, написанную до неё.

Unruin обрезали до одной небольшой картины в голове: вбить ключ SSH, адрес и пользователя, выбрать, что копировать и куда, — всё. Ни агентов, ни программ, которые надо ставить на ваши хосты, ни внешнего менеджера секретов. Здесь записано, что поменялось, почему, и как переписать конфигурацию, написанную раньше.

Если нужна просто текущая картина — читайте GETTING-STARTED.md и CONFIGURATION.md; этот файл про причины и переезд.


Что поменялось, одной таблицей

Область Было Стало
restic на целях (источники-пути) restic надо было поставить на каждый хост Unruin сам доставляет свой статический restic по SSH, если на хосте его нет
Секреты Vaultwarden через bw (vw://), плюс env:///file:///kr:// встроенное шифрованное хранилище kr:// по умолчанию; env:// и file:// остались; vw:// убран
Зеркало мимо restic mode: plain — копия хранилища через rclone убрано — каждое хранилище теперь хранилище restic
Доступ для уборки отдельный prune_access фактически подразумевался необязателен — один access делает всё, пока вы сами не захотите разделения
Зависимости образа restic + rclone + bw (Node) + клиенты баз + docker restic + клиенты баз + docker (rclone и Node/Bitwarden CLI выкинуты)

Всё остальное — рассылка restic copy по нескольким хранилищам, контрольное восстановление, правила хранения, уборка по расписанию, предел времени запуска, панель, оповещения — не менялось.


1. Доставка restic — на хосты ставить нечего

Жалоба, которую это чинит: источники-пути (files, docker_volume) запускают restic на цели, а значит, раньше его приходилось руками ставить на каждый сервер.

Теперь: перед копированием источника-пути Unruin щупает цель по SSH. Есть там годный resticPATH или оставленный Unruin раньше) — берётся он. Нет — Unruin передаёт туда свой статический бинарник в ~/.cache/unruin/restic (атомарная запись и chmod, без root, у пользователя) и работает им. В образе restic и так лежит, поэтому «одолжу свой» не требует никакой настройки.

  • Незаметно: хост, где restic уже есть, не трогают вовсе.

  • Безопасно между архитектурами: Unruin отправляет бинарник своей архитектуры и отказывается при несовпадении, объясняя причину:

    target arch "aarch64" does not match the orchestrator's amd64 restic —
    install restic on the target, or set UNRUIN_RESTIC_PUSH_BIN to a aarch64 binary
    
  • Источникам-потокам (postgres, mysql, command) restic на цели не был нужен и не нужен: дамп льётся в restic --stdin на оркестраторе.

Рычаги:

  • UNRUIN_NO_RESTIC_PUSH=1 — выключить доставку (вернуться к restic из PATH цели, как было раньше).
  • UNRUIN_RESTIC_PUSH_BIN=/путь/к/restic — отправлять этот бинарник вместо собственного (например, другой архитектуры или версии).

Пользователю SSH по-прежнему нужно право читать то, что копируется (и docker volume inspect для docker-томов) — см. SERVER-SETUP.md. Это единственное, что теперь требуется от хоста.

2. kr:// — хранилище секретов по умолчанию; Vaultwarden больше нет

Собственное шифрованное хранилище на AES-256-GCM (kr://) в Unruin было и раньше; теперь оно единственное шифрованное и используется по умолчанию. Значения зашифрованы на диске под UNRUIN_MASTER_PASSPHRASE; в jobs.yaml лежит только ссылка kr://имя, никогда значение. Панель пишет туда напрямую (вставили ключ или пароль — он сохранён и обратно не читается), или через командную строку:

sh
printf %s 'значение-секрета' | unruin secret set restic/minio-primary#password

vw:// (Vaultwarden) и bw убраны целиком. Это снимает самую тяжёлую зависимость: CLI на Node с капризным состоянием сессии, BW_SESSION, плашку «сейф закрыт» в панели. Конфигурация, где всё ещё есть vw://, не загрузится, а сообщение об ошибке приведёт сюда.

У kr:// появилось необязательное #поле, чтобы один логический доступ мог держать несколько значений — например, ключи хранилища S3 как kr://minio/primary#access_key и kr://minio/primary#secret_key. env:// и file:// не менялись и по-прежнему остаются правильным местом для секрета аварийного конверта (см. §5).

3. Хранилища только restic (mode: plain убран)

Режим plain был тупым зеркалом хранилища restic через rclone — «единица» из правила 3-2-1, где на дальнем конце restic нет. Он убран вместе со всей зависимостью от rclone. Каждое хранилище теперь хранилище restic, а mode по умолчанию restic (его можно не писать). Оставшийся mode: plain unruin validate отвергает с внятной ошибкой.

Нужна вторая копия на другой площадке? Заведите второе хранилище restic — Unruin разошлёт туда параллельным restic copy (дедупликация сохраняется за счёт согласованных параметров нарезки), и это строго лучше простого зеркала: зашифровано, дедуплицировано, разворачивается напрямую.

Поддерживаемые бэкенды: local, s3 (включая MinIO, Backblaze, Wasabi), sftp, rest. webdav (у которого не было родного бэкенда в restic и который держался на rclone) убран.

4. prune_access необязателен

Наименьшие права по-прежнему доступны, но больше не удваивают настройку. По умолчанию один access делает всё, включая уборку. prune_access — необязательный привилегированный доступ, который живёт только у оркестратора и никогда не уезжает на цель; задавайте его, когда хотите, чтобы у целей был доступ только на дозапись, а уборка ходила отдельным ключом. Не задан — уборка идёт через access.

5. Что это значит для восстановления после аварии

По форме ничего не изменилось, но частей стало меньше:

  • Секрет аварийного конверта остаётся на env://, подаётся снаружи Unruin (а не из kr://), чтобы аварийное хранилище разворачивалось, имея только конфигурацию из git, этот один секрет и restic. См. RESTORE.md.
  • Новая ответственность: файл хранилища kr:// (secrets.kr в каталоге состояния) и UNRUIN_MASTER_PASSPHRASE — теперь главный корень ваших секретов. Держите их офлайн и впишите мастер-фразу в свой лист восстановления: потерять оба — значит заново вводить каждый секрет kr://. Это тот же размен, который несёт любое хранилище секретов без присмотра; он заменил собой «держать Vaultwarden живым и открытым».

Как переехать со старой конфигурации

  1. Перенесите секреты из Vaultwarden в kr://. Для каждой ссылки vw://папка/запись#поле сохраните значение и поправьте ссылку:

    sh
    export UNRUIN_MASTER_PASSPHRASE='придумайте-длинную-фразу'
    printf %s "$ЗНАЧЕНИЕ" | unruin secret set папка/запись#поле
    

    Затем поменяйте vw://папка/запись#поле на kr://папка/запись#поле в jobs.yaml — грамматика та же, #поле необязательно. Ключи SSH лучше скармливать файлом дословно: unruin secret set ssh/vps-prod-1 < id_ed25519.

  2. Уберите хранилища с mode: plain. Удалите такое хранилище и все записи dest у заданий, которые на него ссылались. Нужна вторая копия — заведите второе хранилище restic и укажите его после основного: Unruin сделает туда restic copy.

  3. Окружение: задайте UNRUIN_MASTER_PASSPHRASE; BW_SESSION и UNRUIN_RCLONE_BIN можно убрать. Сохраните хранилище kr:// и мастер-фразу офлайн (§5).

  4. Пересоберите образ, если собираете сами: Dockerfile больше не ставит rclone и Bitwarden CLI (образ меньше, Node нет).

  5. Проверьте: unruin validate jobs.yaml, затем --preflight для живых проверок. Любые остатки vw:// или mode: plain будут названы, со ссылкой сюда.

Справочник переменных окружения (после чистки)

Переменная Что значит
UNRUIN_MASTER_PASSPHRASE открывает хранилище kr:// (нужна, если используется хоть одна ссылка kr://)
UNRUIN_STATE_DIR где лежат база истории, ключи SSH, known_hosts и secrets.kr
UNRUIN_RESTIC_BIN какой restic запускает оркестратор (по умолчанию restic из PATH)
UNRUIN_NO_RESTIC_PUSH 1 — не доставлять restic на цели автоматически
UNRUIN_RESTIC_PUSH_BIN какой бинарник restic отправлять на цели вместо собственного
UNRUIN_TICK шаг планировщика (по умолчанию 1m)
UNRUIN_LISTEN адрес панели и API (по умолчанию 127.0.0.1:8080; off — выключить)
UNRUIN_API_TOKEN требовать Authorization: Bearer <token> (нужно для адресов не на loopback)
UNRUIN_READONLY запретить любые правки конфигурации через API
UNRUIN_INSECURE осознанный отказ от проверки: адрес не на loopback без ключа

Убраны: BW_SESSION, UNRUIN_RCLONE_BIN.

Бесплатно, целиком ваше, наружу ничего не уходит. Сайт статический: ни аналитики, ни куки, ни внешних запросов.