diff --git a/Caddyfile b/Caddyfile index d146a29..f7010ac 100644 --- a/Caddyfile +++ b/Caddyfile @@ -473,6 +473,18 @@ backup.ginnoir.com { } } +# UrBackup web UI. Clients talk to :55415 directly, not through Caddy. +urbackup.ginnoir.com { + import internal_only + route { + import authentik_outpost + handle { + import authentik_forward_auth + reverse_proxy urbackup:55414 + } + } +} + router.ginnoir.com { import internal_only reverse_proxy 192.168.1.1 diff --git a/bookmarks-domains.html b/bookmarks-domains.html index f237f5a..c068706 100644 --- a/bookmarks-domains.html +++ b/bookmarks-domains.html @@ -12,11 +12,6 @@
foundry2

-

TABLETOP TOOLS (public)

-

-

5etools -

-

FILE STORAGE — internal only (Nextcloud) (internal)

files @@ -24,6 +19,7 @@

STATIC SITES (public)

+

5etools
wa4

@@ -95,6 +91,7 @@

webui [internal]
imgstudio [internal]
backup +
urbackup [internal]
router [internal]

diff --git a/stacks/devicebackup/README.md b/stacks/devicebackup/README.md new file mode 100644 index 0000000..a235dfa --- /dev/null +++ b/stacks/devicebackup/README.md @@ -0,0 +1,112 @@ +# devicebackup stack + +Full backups of the household laptops onto valhalla. + +| Device | Disk | Tool | Cap | +|---|---|---|---| +| Windows laptop A | 1 TB | UrBackup image backups | shared 3.5 TB soft quota | +| Windows laptop B | 512 GB | UrBackup image backups | (same) | +| MacBook (hub) | 1 TB | Time Machine → `tm-hub` share | 1.5 TB | +| MacBook (wif) | 1 TB | Time Machine → `tm-wif` share | 1.5 TB | + +Worst case (every disk full) that's ~6.5 TB on `storage1`. It had 16 TB free on 2026-10-01 +(84% used); keep an eye on pool fill, since ZFS slows down past ~90%. + +**storage1 has no redundancy.** Treat this as the *second* copy of each laptop, not the only one, +until the mirror rebuild is done. + +## Windows: UrBackup + +### Before first deploy (host) + +```bash +sudo install -d -o ginnoir -g ginnoir /config/urbackup /storage1/labdata/urbackup +``` + +Register a new Portainer git stack → `stacks/devicebackup` (one-time), then push. + +### Server settings (web UI → Settings) + +- **General → Server:** backup storage path `/backups`. +- **General → Internet:** enable internet mode, server name `urbackup.ginnoir.com`, port `55415`; + tick **"Do image backups over internet"** and **"Do full file backups over internet"**. +- **General → Soft filesystem quota:** `3500G`. +- **Client defaults → Image backups:** incremental every 1 day, full every 30 days; + keep min 2 / max 4 full images, min 7 / max 30 incrementals. Volumes `ALL_NONUSB` (with ESP). +- **Client defaults → File backups:** off (images are browsable and mountable for single-file restores). +- Leave UrBackup with **no admin user**: auth is Authentik forward_auth at Caddy, and 55414 is not + published. Adding a UrBackup user just means logging in twice. + +### Each Windows laptop + +1. Web UI → **Add client → Internet/active client**, name it, and download the per-client installer + (it embeds the server address + auth key). +2. Run it on the laptop. The first full image takes a long time on Wi-Fi, so do it at home, plugged in. +3. **Make the restore USB:** download the UrBackup restore ISO and keep a stick around. A bare-metal + restore boots it, connects to the server on the LAN, and writes the image back. +4. BitLocker: images contain the *decrypted* volume. The data is protected only by valhalla's own security. + +## macOS: Time Machine (host smbd) + +Host `smbd` already serves `[storage1]` on :445, so Time Machine goes on the host Samba rather than +a container (Macs handle SMB on a non-standard port poorly). This config is **host-managed**, not +deployed from this repo. Keep this section in sync with `/etc/samba/smb.conf`. + +Add to `[global]` (fruit has to be global, because macOS negotiates the AAPL extensions on the +first tree connect): + +```ini + vfs objects = catia fruit streams_xattr + fruit:metadata = stream + fruit:model = MacSamba + fruit:posix_rename = yes + fruit:veto_appledouble = no + fruit:nfs_aces = no + fruit:wipe_intentionally_left_blank_rfork = yes + fruit:delete_empty_adfiles = yes +``` + +One share per Mac, so each Mac gets its own 1.5 TB cap: + +```ini +[tm-hub] + path = /storage1/labdata/timemachine/hub + valid users = timemachine + read only = No + fruit:time machine = yes + fruit:time machine max size = 1500G + +[tm-wif] + path = /storage1/labdata/timemachine/wif + valid users = timemachine + read only = No + fruit:time machine = yes + fruit:time machine max size = 1500G +``` + +Done on 2026-10-01: `timemachine` user + Samba password (password is in `stack.env`), and +`/storage1/labdata/timemachine/{hub,wif}` (owned by `timemachine`, mode 0700). + +The full target config is **staged** at `/etc/samba/smb.conf.timemachine-pending`, already +`testparm`-validated. It is *not* live yet, because smbd re-reads `smb.conf` automatically +whenever the file changes. Apply it when nothing is mid-copy on `[storage1]`: + +```bash +sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak-$(date +%F) && sudo mv /etc/samba/smb.conf.timemachine-pending /etc/samba/smb.conf && sudo systemctl reload smb +``` + +Samba registers the shares with avahi (already running), so on the LAN they show up directly in +**System Settings → General → Time Machine → Add Backup Disk**. Pick the share, enter the +`timemachine` credentials, and **turn on "Encrypt backup"**. Away from home, Bonjour doesn't cross +Tailscale, and valhalla has no MagicDNS name (the tailnet reaches it via the subnet route), so +when re-adding remotely use the LAN IP: + +```bash +sudo tmutil setdestination -a "smb://timemachine@192.168.1.69/tm-hub" +``` + +## Verify + +- [ ] Each Windows laptop: one full image completes, then **mount it in the UrBackup UI and open a file**. +- [ ] Each Mac: first backup completes, then **Enter Time Machine and restore one file**. +- [ ] Uptime Kuma: HTTP monitor on `https://urbackup.ginnoir.com`, TCP monitor on `valhalla:55415`. diff --git a/stacks/devicebackup/docker-compose.yml b/stacks/devicebackup/docker-compose.yml new file mode 100644 index 0000000..a4b0a3d --- /dev/null +++ b/stacks/devicebackup/docker-compose.yml @@ -0,0 +1,32 @@ +# devicebackup stack — full backups of the household laptops onto valhalla. +# +# Windows laptops → UrBackup (this stack): incremental disk images, bare-metal restore. +# MacBooks → Time Machine over the HOST smbd (not in compose — host already owns +# :445, see README.md for the smb.conf shares). +# +# Clients run in UrBackup "internet mode" against urbackup.ginnoir.com:55415, which resolves +# to valhalla on the LAN and over the tailnet, so laptops keep backing up away from home. +# The web UI (55414) is only reachable through Caddy + Authentik forward_auth. +# +# Not part of the Kopia → B2 offsite set (stacks/backup) — this is copy #2 of each laptop. + +services: + urbackup: + container_name: urbackup + image: uroni/urbackup-server:2.5.x + restart: unless-stopped + labels: + - "com.centurylabs.watchtower.enable=false" + networks: [edge] + env_file: + - stack.env + volumes: + - /config/urbackup:/var/urbackup + - /storage1/labdata/urbackup:/backups + ports: + - "55415:55415" # internet-mode clients (LAN + tailnet) + +networks: + edge: + name: edge + external: true diff --git a/stacks/devicebackup/stack.env b/stacks/devicebackup/stack.env new file mode 100644 index 0000000..e5f5406 --- /dev/null +++ b/stacks/devicebackup/stack.env @@ -0,0 +1,11 @@ +# devicebackup stack — UrBackup server. +TZ=America/Chicago + +# Run as ginnoir so /config/urbackup and /storage1/labdata/urbackup stay ginnoir-owned. +PUID=1000 +PGID=1000 + +# Samba password for the host-managed Time Machine shares (tm-hub, tm-wif). +# Not read by the container; lives here so it is versioned with the stack (see README). +TIMEMACHINE_SMB_USER=timemachine +TIMEMACHINE_SMB_PASSWORD=Ey6gC0IL3rtm6nNL7oV3e08M