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

92 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-пути (для секретов бэкапов, если есть)