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:
co-authored by
Claude Fable 5
parent
80f0219716
commit
a0e3a7dd86
@@ -1,5 +1,10 @@
|
||||
# Personal infrastructure notes
|
||||
|
||||
Two repositories back this setup:
|
||||
[**doc**](https://git.lutran.fr/julien/doc) (this one) and
|
||||
[**scripts**](https://git.lutran.fr/julien/scripts) (the cron drivers
|
||||
and their config files, deployed to `/root/scripts` on each host).
|
||||
|
||||
**Start here**:
|
||||
- [backup-strategy.md](backup-strategy.md) — what is
|
||||
backed up, by which tool, on what schedule, and how to restore.
|
||||
@@ -7,97 +12,12 @@ backed up, by which tool, on what schedule, and how to restore.
|
||||
service to ks4 (and getting it backed up automatically).
|
||||
|
||||
**Tech notes**
|
||||
- [`nuc/`](nuc/) — home lab on `nuc` (see below)
|
||||
- [`ks4/`](ks4/) — prod server `ks4` at OVH (see below)
|
||||
- [`nuc/`](nuc/README.md) — home lab on `nuc`: host, storage, instances
|
||||
- [`ks4/`](ks4/README.md) — prod server `ks4` at OVH: host, services, network flows
|
||||
- [`ks2/`](ks2/) — legacy backup server being [decommissioned](ks2/plan.md)
|
||||
- [`archer-c7/`](archer-c7/) — home router (TP-Link Archer C7 v5 running on OpenWrt)
|
||||
|
||||
## Homelab: nuc
|
||||
|
||||
Incus host on the LAN.
|
||||
|
||||
- Debian 13, Intel Alder Lake-N (iGPU `i915`, shared by both Jellyfin containers) —
|
||||
bare-metal reinstall: [nuc/nuc-install.md](nuc/nuc-install.md)
|
||||
- Instances are bridged onto the LAN (192.168.0.0/24)
|
||||
- USB 4 TB WD Red: ZFS pool `usb4t` — `usb4t/backup` → `/backup`
|
||||
(incus exports, `nuc/` + `ks4/` subdatasets, 1 TB quota) and
|
||||
`usb4t/media` → `/srv/media` (media library, shared into containers
|
||||
via `shift=true` disk devices; works because ZFS ≥ 2.2 supports
|
||||
idmapped mounts)
|
||||
- Backups: all local instances replicated to the USB pool
|
||||
(`/root/scripts/incus-copy.sh -p backup -s nucbackup`; replicas
|
||||
stopped, autostart off) — see
|
||||
[nuc/nuc-install.md](nuc/nuc-install.md); ks4 replicas pulled into
|
||||
pool `ks4backup` — see [ks4/incus-copy.md](ks4/incus-copy.md)
|
||||
|
||||
### Instances
|
||||
|
||||
| Name | IP | Doc | Features |
|
||||
|---|---|---|---|
|
||||
| [jellyfin-server](nuc/jellyfin-server.md) | 192.168.0.5 | ✅ | unprivileged, autostart; iGPU render node (`gpu` device, render gid) for QSV/VAAPI transcoding; `/srv/media` disk device (`shift=true`); proxy device → host :8096 |
|
||||
| [jellyfin-client](nuc/jellyfin-client.md) | 192.168.0.6 | ✅ | **privileged**, autostart; full iGPU (`gpu` device, gid 44) → HDMI kiosk (cage + Jellyfin Media Player); custom `raw.lxc` (bind `/dev/snd`, `/dev/input`, host `/run/udev`); Pioneer USB audio as ALSA default; FR keymap; go-librespot Spotify Connect ("Pioneer A-70") |
|
||||
| [transmission-bt](nuc/transmission-bt.md) | 192.168.0.7 | ✅ | unprivileged, autostart; always-on WireGuard full tunnel → ks4 (egress = 193.70.35.17, kill switch: no default route); `/srv/media` disk device (`shift=true`), downloads to `/media/downloads`; web UI :9091 (LAN only) |
|
||||
| blocky | 192.168.0.254 | — | unprivileged, autostart; DNS ad-blocker |
|
||||
| privoxy | 192.168.0.11 | — | unprivileged, autostart; filtering HTTP proxy |
|
||||
| homeassistant | (stopped) | — | **virtual machine**, 50 GiB root disk on pool `data` |
|
||||
|
||||
## 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:
|
||||
[ks4/install.md](ks4/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
|
||||
[ks4/install.md](ks4/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)**
|
||||
([ks4/local-backup-cron.md](ks4/local-backup-cron.md),
|
||||
[ks4/incus-copy.md](ks4/incus-copy.md),
|
||||
[ks4/restic-backup.md](ks4/restic-backup.md)).
|
||||
|
||||
## Network flows
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
### Conventions
|
||||
## Conventions
|
||||
|
||||
- One markdown file per topic in the correct subdir, containing the full
|
||||
implementation notes, configuration, and troubleshooting notes.
|
||||
@@ -107,4 +27,5 @@ fixed endpoint; ks4's incus API is never exposed to the internet.
|
||||
- Adding a service to ks4: follow
|
||||
[new-container.md](new-container.md) (no Docker in containers —
|
||||
incus runs OCI images natively and `incus-compose` handles stacks;
|
||||
data paths go into `scripts/restic-paths`).
|
||||
data paths go into
|
||||
[`scripts/restic-paths`](https://git.lutran.fr/julien/scripts/src/branch/main/restic-paths)).
|
||||
|
||||
Reference in New Issue
Block a user