doc: split per-host READMEs, gitea cross-repo links, consistency pass

- nuc/README.md and ks4/README.md carry the host sections (+ network
  flows) that lived in the top-level README; links rebased
- top README: repo links (doc/scripts on git.lutran.fr), index points
  at the new per-host pages
- cross-repo references now use https://git.lutran.fr/julien/scripts
  instead of relative ../scripts paths that resolve nowhere
- plakar-s3-data.md and plakar-incus-integration.md marked SUPERSEDED
  / RETIRED with pointers to restic-backup.md; their measurements and
  rationale kept
- install.md, local-backup-cron.md, incus-copy.md: crontab sections
  updated to the live schedule (01:00 replicas, 05:00 restic, Sun
  maintenance); retired legs labelled as such
- restic-backup.md: status live, cutover recorded, post-GC memory
  estimate, seed plan dated
- seafile-gc.md: online GC noted, stale 'crons commented out' removed
- ks2/: what-ks2-does-today rewritten (nothing writes to it any more),
  legs table and gates reflect restic, decommission steps updated
- db-exclude replaces the plakar-era config name (script keeps a
  fallback)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Julien Lutran
2026-08-28 16:04:07 +02:00
co-authored by Claude Fable 5
parent 80f0219716
commit a0e3a7dd86
16 changed files with 246 additions and 193 deletions
+55
View File
@@ -0,0 +1,55 @@
# Prod: ks4
Incus host at OVH — public-facing self-hosted services.
- Debian 13, Xeon D-1521 / 32 GiB, 2× 6 TB (OS on mdraid RAID1,
ZFS pool `data` on `sda5`) — setup & rebuild:
[install.md](install.md)
- SSH: `ssh -i id_rsa_claude -p 2233 julien@193.70.35.17`
(`julien` has passwordless `sudo incus …`)
- Instances are on a NAT bridge `incusbr0` (192.168.1.0/24); public
ingress via Incus proxy devices. `gateway` (nginx) is the sole HTTP/S
entry point and fans out to the app containers.
- Services: gateway, mail, nextcloud, seafile, git, freshrss, bitwarden,
outline, login (SSO), wireguard, + more — full table in
[install.md](install.md).
- ⚠️ The ZFS `data` pool is single-disk (not mirrored); durability
rests on nightly cron jobs — 01:00 `incus copy --refresh` of all
instances to the local `backup` pool on sdb5, then the instance leg
to S3; 05:00 restic (DB dumps + data trees) to S3; nuc pulls the
replicas over WireGuard. Full picture and restore procedures:
**[backup-strategy.md](../backup-strategy.md)**
([local-backup-cron.md](local-backup-cron.md),
[incus-copy.md](incus-copy.md),
[restic-backup.md](restic-backup.md)).
## Network flows (nuc ↔ ks4)
```
nuc — home LAN 192.168.0.0/24 ks4 — OVH 193.70.35.17
+-----------------------------------+ +-------------------------------------+
| | | |
| host: wg-ks4 (10.8.0.20) | | [wireguard] 192.168.1.18 |
| incus remote "ks4" ------+--WG-->| wg0 10.8.0.1/24, udp 51845 |
| pull ks4:* -> pool ks4backup | udp | | masquerade -> eth0 |
| on usb4t [pending FTTH seed] | 51845 | | |
| | | +-> incus API 192.168.1.1:8443 |
| [transmission-bt] wg0 (10.8.0.21) | | | (ufw: only from .18) |
| full tunnel 0.0.0.0/0 ------+--WG-->| | |
| kill switch: no default route | udp | +-> WAN egress: torrents + |
| downloads -> /srv/media | 51845 | apt of transmission-bt |
| (usb4t/media, read by jellyfin) | | exit as 193.70.35.17 |
| | | |
| 03:00 instance snapshots | | 03:00 instance snapshots |
| 03:30 incus-copy: all instances | | 01:00 incus-copy: all instances |
| -> project backup, pool | | -> project backup, zpool sdb5 |
| nucbackup (usb4t/backup/nuc) | | then restic instance leg -> S3 |
| 05:00 pull ks4:* -> ks4backup | | 05:00 restic: DB dumps + data |
| [pending FTTH] | | trees -> S3 (restic-data) |
| 05:30 apt upgrade all containers | | Sun 14:00 restic maintenance |
+-----------------------------------+ +-------------------------------------+
phones/laptops: WG peers 10.8.0.2-3 reach 192.168.1.x through the same endpoint
```
Both tunnels initiate **from** nuc (home NAT, dynamic IP) toward ks4's
fixed endpoint; ks4's incus API is never exposed to the internet.