Files
nixos/.agent/decisions/0002-backups-external.md
T
oqyude 0df9688643 fix(review-T17): apply review fixes B1/I1/I2/M1/M2 + T10+T15+any.nix+wsl cleanup
Review of dev vs 16644fc found 1 BLOCKING + 3 IMPORTANT + 2 MINOR.
All addressed in this commit:

B1 (R1.4 stale files in project-rules.md + AGENTS.md):
  Replaced 'vds/nginx.nix' (removed in ef38dc4) with 'home/termux.nix'
  (added in 958247b). R1.4 now correctly lists the 4 files that use
  100.64.0.0: home/termux.nix:256, modules/server/nextcloud.nix:73,
  modules/server/nginx.nix:109,253, modules/vds/systemd.nix:10.

I1 (count drift in '15 modules' docs):
  - AGENTS.md:84 + project-rules.md:97: '15 → 14' (with note that
    stirling-pdf was deleted in 5dd7a58)
  - manifest.json (T16): rewritten acceptance to '15 archived
    (13 from server/default.nix:37-50 + 2 from containers/ kokoro-tts
    and openhands) + 1 deleted (stirling-pdf) + 1 active (open-webui
    in containers/)'
  - modules/server/default.nix:37-50: comment now explains the
    three categories

I2 (T1 + T13 status stuck on pending):
  Both flipped to 'completed' in manifest.json. T1 import fix
  verified by nix eval (epral stateVersion = '24.05'). T13 done in
  61b3724 (nginx firewall rule removed). I3 (.ci/checks.sh committed)
  satisfied.

M1 (R1.3 stale nginx.nix:225 line number):
  Removed line number from both project-rules.md and AGENTS.md.
  Replaced with 'nginx.nix (networking.firewall)'.

M2 (R1.2 listed 7 services, 2 in archive):
  Updated to 12 actual services in both files. n8n and minecraft
  were archived in T16; they no longer need storage guard.

T10 (reality443Forwarding погашен):
  Removed option from options.nix:66-74, realityPorts from
  3x-ui.nix:33-35, and 'reality443Forwarding = true' from
  vds/default.nix:19. ADR-note comments left in place.

T15 (kokoro-tts and openhands archived):
  git mv modules/containers/kokoro-tts.nix → archive/containers/
  git mv modules/containers/openhands.nix → archive/containers/
  Also moved modules/containers/kokoro-tts/ (Dockerfile, app.py, etc.)
  to archive/containers/kokoro-tts/ for completeness.

any.nix (nix flake check support):
  Added stub fileSystems + boot.loader.grub to configurations/any.nix
  so 'nix flake check' can evaluate the 'default' template config
  (which is never deployed — real hosts have their own disko/grub).

wsl cleanup (dead imports blocking nix flake check):
  - Removed modules/wsl/containers/default.nix (was only imported
    nowhere, contained kokoro-tts reference)
  - Removed './containers' import from modules/wsl/default.nix
    (resolved to the now-removed default.nix)

nix flake check: previously failed with 'Path modules/containers does
not exist' (cached evaluation referenced old path). After this commit
the error is gone — flake check progressed past the path resolution
and started building derivations. Full build output not captured
(5-min timeout for download from cache.nixos.org), but path errors
are resolved.

T5 risk acknowledgment:
  .agent/decisions/0002-backups-external.md updated with explicit
  risk table for 'if no backups' scenario + ADR/R1.9 guidance.

T1, T2, T6, T7, T8, T9, T10, T12, T13, T15, T16, T17: all → completed
in manifest.json. T3, T4, T5, T11, T14: previously completed.
Remaining DEFERRED: T3 (otrecа SSH recovery), T5 (5.6 answer).
2026-10-10 16:25:52 +03:00

7.2 KiB
Raw Blame History

Backups — external to Nix, not declared in this repo

Status: documented (not complete — awaiting answer to open question 5.6) Date: 2026-10-09 Related: open question 5.6 in .agent/roadmap/sources.md, task T5/B2 in .agent/tasks/manifest.json

TL;DR

Резервные копии критичных сервисов sapphira (PostgreSQL, Immich, Nextcloud, Gitea, Homebox, Navidrome, Calibre-Web, 3x-ui-панель, TapeRotation) не управляются через Nix-конфиг. Они выполняются внешней по отношению к этому репозиторию системой, спецификация которой здесь не зафиксирована.

Что декларируется в Nix (для ориентира)

Сервис Данные Где лежат (внешний диск) Guard есть (T4)
PostgreSQL БД xlib.dirs.services-mnt-folder/postgresql ✓
Immich медиа + метаданные xlib.dirs.services-mnt-folder/immich ✓
Nextcloud файлы + БД xlib.dirs.services-mnt-folder/nextcloud ✓
Gitea git-репы + БД ${xlib.dirs.services-mnt-folder}/gitea ✓
Homebox SQLite ${xlib.dirs.services-mnt-folder}/homebox ✓
Navidrome плейлисты + метаданные ${xlib.dirs.server-home}/Music ✓
Calibre-Web библиотека + БД ${xlib.dirs.services-mnt-folder}/calibre-web(-library) ✓
3x-ui панель конфиг + sqlite-БД ${services-nodes-folder}/${hostname}/3x-ui ✓
TapeRotation SQLite + uploads ${services-nodes-folder}/${hostname}/tape-rotation ✓
Syncthing config + data ${xlib.dirs.server-home} ✓

Все эти пути — на xlib.dirs.server-home (т.е. на /home/oqyude/External, реальная ФС, не bind-mount). Storage guard (T4) гарантирует, что сервисы не стартуют на пустой БД, если External не смонтирован — это уменьшает окно для silent data corruption, но не заменяет бэкапы.

Что НЕ декларируется в Nix (нужно уточнить)

Открытый вопрос 5.6: «Где бэкапы и как проверять?»

Конкретно неизвестно:

  • Где физически лежат бэкапы (другой диск? NAS? offsite? S3?)
  • Какая схема (full / incremental / snapshot / pg_dump / tar / rsync / btrfs-send)
  • Какая частота и какой retention (30 дней? 90? год?)
  • Какие сервисы покрыты (все 9 из таблицы выше? только PostgreSQL?)
  • Как проверять восстановление (drill раз в квартал? никогда?)
  • Шифрование бэкапов at-rest (gpg? LUKS? clear?)
  • Offsite-копия (есть? куда?)

Что из Nix-репо с этим связано

  • modules/containers/tape-rotation.nix — панель трекинга физических tape-картриджей, не система бэкапов. База данных SQLite в services-nodes-folder/.../tape-rotation/db/. Сама панель бесполезна без процесса, который физически пишет на ленты.
  • lib/xlib/helpers.nix:mkServiceStorage — описывает, как сервисы размещают данные на External, но не описывает, как эти данные бэкапятся.
  • R1.2 (storage guard) — защищает от «сервис стартанул на пустой БД», но не от «External-диск умер, и бэкапов тоже нет».

Что нужно сделать (когда появится ответ на 5.6)

  1. Описать систему бэкапов в этом файле (или новом 0002-backups.md):
    • Где лежат
    • Какой retention
    • Как проверяются
  2. Если есть скрипты — добавить их в modules/server/ или pkgs/ с явным комментарием «backup script — not auto-tested, owner responsibility».
  3. Добавить CI-check (T15): по возможности автоматически проверять, что бэкап-каталог не пустой (если это определимо из Nix-репо).
  4. Если retention > 30 дней — рассмотреть R1.x-инвариант «бэкапы верифицируются N раз в год», чтобы это не «забывалось».

Текущее состояние (по умолчанию)

В этом репозитории не декларируется ни одна бэкап-стратегия. Если бэкапы есть — они живут вне S:/Git/nixos. Если их нет — это риск, который должен явно зафиксировать владелец (открытый вопрос 5.6 в .agent/roadmap/sources.md).

Risk acknowledgment (если бэкапов нет)

Если на вопрос 5.6 ответ «бэкапов нет» — фиксируем явно:

Failure mode Без бэкапа С бэкапом
/dev/sdc1 (External) умирает Потеря ВСЕХ 9 сервисов (БД, медиа, конфиги) Восстановление с последнего снапшота
Ошибочный nixos-rebuild switch Конфиг откатывается через generation, но данные — нет Откат + восстановление данных
rm -rf на External Безвозвратная потеря Восстановление
Container corruption (postgresql data dir) Storage guard (T4) не стартует сервис, но данные не спасает Восстановление из бэкапа
3x-ui panel.db corruption Xray-конфиги (inbound'ы, клиенты) потеряны, R1.5 нарушен Восправление panel.db

Если бэкапов действительно нет — это нужно зафиксировать как принятый риск (ADR), а не как «не знаю». Документ 0002-backups-external.md переходит в статус accepted, в R-секции project-rules.md добавляется инвариант R1.9: «Бэкапы не выполняются. Потеря External = полная потеря 9 сервисов. Решение владельца».

Если бэкапы есть — заполняем секцию «Что есть» выше конкретными путями/расписанием/retention и фиксируем R1.x про регулярную верификацию.


См. также:

  • .agent/roadmap/sources.md — открытый вопрос 5.6
  • .agent/rules/project-rules.md — R1.2 (storage guard)
  • .agent/tasks/manifest.json — T5/B2 (этот документ)
  • ADR-0001 — sops-пути (для секретов бэкапов, если есть)