43ef0e54475284678ac59056af5596d58a3b14cb
Add udev rule + oneshot service + script on nuc that restart the container kiosk when the Logitech Unifying receiver is replugged, since hotplug uevents don't cross into the container's netns and cage only enumerates input at startup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
perso
Personal infrastructure notes.
Homelab: nuc
Incus host on the LAN.
- Host:
nuc—192.168.0.3, Debian 13, Intel Alder Lake-N (iGPUi915, shared by both Jellyfin containers) — bare-metal reinstall: nuc/nuc-install.md - SSH:
ssh -i id_rsa_claude root@192.168.0.3(keys at repo root, gitignored) - 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) andusb4t/media→/srv/media(media library, shared into containers viashift=truedisk devices; works because ZFS ≥ 2.2 supports idmapped mounts) - NAS:
//192.168.0.10/Shared(CIFS) — original media source, normally offline; not mountable into containers (idmapped mounts unsupported on CIFS) - 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; ks4 replicas pulled into poolks4backup— see ks4/incus-copy.md
Instances
| Name | IP | Doc | Features |
|---|---|---|---|
| jellyfin-server | 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 | 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 | 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 |
| pihole | (stopped) | — | unprivileged; superseded by blocky |
| homeassistant | (stopped) | — | virtual machine, 50 GiB root disk on pool data |
Prod: ks4
Incus host at OVH — public-facing self-hosted services.
- Host:
ks4.lutran.fr—193.70.35.17, SSH on port 2233, Debian 13, Xeon D-1521 / 32 GiB, 2× 6 TB (OS on mdraid RAID1, ZFS pooldataonsda5) — setup & rebuild: ks4/install.md - SSH:
ssh -i id_rsa_claude -p 2233 julien@193.70.35.17(julienhas passwordlesssudo 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.
- ⚠️ The ZFS
datapool is single-disk (not mirrored); durability rests on two nightly root cron jobs —incus copy --refreshto remote hostks2(moving to nuc poolks4backup, see ks4/incus-copy.md), and an rsync backup (scripts/incus-backup.sh) to164.132.173.57:/backup/ks4.
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 |
| nucbackup (usb4t/backup/nuc) | | backup (sdb5) [planned] |
| 05:00 apt upgrade all containers | | 04:00 incus-backup.sh: DB dumps |
| | | -> /backup (sdb5) [planned] |
+-----------------------------------+ +-------------------------------------+
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
- One markdown file per instance in
nuc/, containing the full install script (idempotent-ish, run as root on the host), first-run configuration, and troubleshooting notes. - Containers are built from
images:ubuntu/24.04and configured exclusively throughincus exec/incus configso the doc is the single source of truth — rebuilding = re-running the script.
Languages
Markdown
100%