Minecraft instances are flushed to disk (save-all) and snapshotted while
the server keeps running — no player disruption. All other services stop
briefly for filesystem-consistent database snapshots, then restart.
Also update file header, install banner, schedule description, and README.
https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
- minecraft: prompt for world seed on new installs (skipped if world already exists); SEED env var wired into docker-compose.yml
- disaster-backup: new service that stops each Docker service, snapshots the full ~/docker/<service>/ directory (config + data + databases), then restarts it — multi-destination support so different services can go to different drives/repos; one restore_kopia_backup.sh per destination
- README: update backup row to list both backup and disaster-backup
https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
- extras/restore_kopia_backup.sh: interactive restore tool — lists all
snapshot sources, pick source + snapshot, choose inspect (restore to
/tmp) or restore-in-place (moves current data aside as .pre-restore-DATE
for easy rollback, auto-stops/starts the associated Docker service)
- services/backup.sh: copy restore script to ~/docker/backup/ during
install; update summary to show restore command
- CLAUDE.md: add note to update README services table when adding a
service; add Authelia section documenting which services have built-in
auth, the import-authelia Caddy pattern for no-auth services, and
remember_me_duration config for kiosk/persistent sessions
https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
Documents all packages installed by the base service, and adds a
Backup section covering Kopia, Borg, plain rsync, rsync --link-dest
(versioned snapshots with original folder structure), and rsnapshot —
with guidance on when to use each.
https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
Keep only the two base install scripts (24.04, 26.04), the modular
system (setup.sh, lib/, services/, extras/, bootstrap.sh), and
LICENSE/README/VERSION. Everything else was superseded.
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
- SCP example used $(whoami) which evaluates to root; use $ACTUAL_USER instead
- VT_VERSION stripped to major.minor (e.g. 1.21) so the picker version
prompt is correct; previous awk printed the full patch string (1.21.4)
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
When you open the USB folder in the file manager, you're already there.
Right-click → Open in Terminal → sudo bash bootstrap.sh, or double-click
bootstrap.sh → Run in Terminal → sudo prompt. No /media/whoami/DRIVENAME
path hunting required.
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
The real workflow is: GitHub Code → Download ZIP → unzip → copy to USB.
No git, no auth, no file manager tricks. On the target machine: ls to find
the drive name, then sudo bash /media/$(whoami)/DRIVENAME/...bootstrap.sh.
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
bootstrap.sh: add self-elevation — if not root, re-exec under sudo.
Double-clicking the script in GNOME ("Run in Terminal") now prompts for
the sudo password automatically, no extra commands needed.
README: rewrite USB section around the real workflow:
- clone with "Open in Terminal" from the file manager sidebar
- Option A: right-click folder → Open in Terminal → sudo ./setup.sh
- Option B: double-click bootstrap.sh → "Run in Terminal?" → sudo prompt
- note on nautilus-extension-gnome-terminal and exFAT vs ext4
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
README: rewrite USB section with three steps:
1. Auto-detect USB mount point and clone repo onto it
2. Install nautilus-extension-gnome-terminal for right-click "Open in Terminal"
3. Double-click "Run Setup.desktop" to launch wizard with sudo (no terminal needed)
Run Setup.desktop: launcher file included in the repo so it's present on the
USB automatically. Uses %k to find its own location, cds to that directory,
and runs sudo ./setup.sh in a terminal window.
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
The USB section was documenting the wrong thing. Replace with instructions
for carrying the repo on a USB stick and running setup.sh directly from it
on any fresh Ubuntu machine — no internet required for the repo.
Covers: cloning/copying to USB, finding the mount point on the target
machine, running setup from USB, exFAT vs ext4 trade-offs, fixing
permissions after copy.
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
- lib/common.sh: require_docker now installs Docker CE + Compose plugin
via get.docker.com instead of erroring out if Docker is missing.
Also adds the calling user to the docker group automatically.
- README.md: fix 'tells you how to install Docker' → 'installs Docker
automatically'; add full USB drive usage section (mount, fstab,
DOCKER_DIR config, moving existing data, tips).
- services/minecraft.sh: replace single-source whitelist import with the
multi-source UI from the updated setup-minecraft.sh — collects players
from the current instance, saved backup files, and other servers' backups;
assigns letters to each source so you can import by letter (all from that
source) or by number (specific player).
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
Added exec sudo bash self-elevation so bootstrap.sh works correctly when
double-clicked ("Run in Terminal") without the user needing to prefix sudo.
If already root, the check is a no-op.
Removed bootstrap.desktop — too fragile across desktop environments.
README now covers both "Open in Terminal" and double-click paths.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
The previous USB instructions assumed git was available. Added step-by-step
for the no-git path: GitHub ZIP download → unzip → copy to USB → run
bootstrap.sh. Includes the Ubuntu auto-mount path tip for finding the
drive name. Folder name note (ubuntu-post-install-main from ZIP) added.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Three usage modes now documented and implemented:
1. Public repo: curl | sudo bash (unchanged)
2. Private repo, USB: copy whole repo to thumb drive, run bootstrap.sh
from it — detects setup.sh alongside itself, copies to ~/ubuntu-post-install,
execs setup.sh. No git auth, no internet needed for the scripts.
3. Private repo, PAT: bootstrap.sh --pat ghp_xxx — PAT stripped from
stored remote URL after clone so it is not saved in plain text.
USB mode is the recommended approach for private repos: clone once,
put on a drive, run on every new machine.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
bootstrap.sh: one curl | sudo bash to get and run on a fresh box —
installs git if missing, clones/updates the repo, execs setup.sh.
README.md: complete rewrite. The old README described the monolithic
script (--restore, --migrate flags, Samba, NetBird, etc.) which no
longer exists. New README covers quick start, usage modes, service
table, layout, and managing installed services.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Both silent-send and immich already use NodeSource (not Ubuntu repos).
Node 24 is the current active LTS; 22 moves to maintenance in 2025.
Minimum version checks (>=18 and >=20) are unchanged — both services
accept any sufficiently recent Node.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Probe for --break-system-packages support once (pip --help, cached in
_PIP_HAS_BSP) rather than comparing Ubuntu version numbers. Works on any
pip >= 22.3 regardless of distro; older pip (Ubuntu 22.04, pip 22.0)
falls back to --user only, which is correct there since PEP 668 isn't
enforced on 22.04 anyway.
The flag name is scary but harmless with --user: installs go to ~/.local/
which apt never manages regardless.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
pip3 install --user alone does not reliably bypass PEP 668 in all 24.04
environments. --break-system-packages (pip 22.3+) is the correct override.
Flag is only added when ubuntu_version_ge "24.04" so it does not run on
Ubuntu 22.04 where pip 22.0 ships and the flag is not yet supported.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
lib/common.sh:
- detect_os(): reads /etc/os-release into OS_DISTRO, OS_VERSION,
OS_CODENAME globals (exported, auto-called on source)
- ubuntu_version_ge(): numeric version comparison helper
- pip_user_install(): central wrapper for pip3 install --user so any
future version-specific flags are in one place
setup.sh:
- Both header banners now show detected OS line (e.g., "Ubuntu 24.04 (noble)")
- First-run path warns if not Ubuntu or < 24.04
services/sky-cam.sh, services/sync-cc.sh:
- Replace inline pip3 invocations with pip_user_install helper
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
On second run, is_installed base (command -v ncdu) detects that base
packages are already present and jumps straight to the service menu,
skipping the required-setup banner, confirm prompt, and apt-get install.
The first-run path is unchanged; `sudo ./setup.sh base` forces reinstall.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Introduces a one-time configuration wizard (sudo ./setup.sh configure)
that stores SITE_TZ, SITE_DOMAIN, and SITE_CADDY_NET in ~/docker/.config.
Every service now uses these as prompt defaults so the user types common
values once instead of re-answering the same questions for each service.
- lib/common.sh: load_site_config / save_site_config; auto-loads on source;
backward-compat BASE_DOMAIN alias kept for old .config files
- setup.sh: run_site_configure wizard; first-run offer after base install;
`sudo ./setup.sh configure` command to update defaults at any time
- 14 services: TZ_VAL now honours SITE_TZ, falling back to /etc/timezone
- 3 inline-heredoc services (filebrowser, homeassistant, ntfy): same fix
- authelia: SITE_TZ/SITE_DOMAIN as prompt defaults; SITE_CADDY_NET replaces
hardcoded caddy_net throughout (env, compose patch, network creation)
- minecraft, frigate-audio: simplify BASE_DOMAIN read to use SITE_DOMAIN
- sky-cam: SITE_TZ as default for timezone prompt
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Three bugs fixed:
1. git clone ran as root — SSH key lookup failed because user's keys are in
~user/.ssh/, not /root/.ssh/. Both SSH and PAT clones now run via
sudo -u ACTUAL_USER so git uses the right key and the clone is owned
correctly without a separate chown step.
2. 2>/dev/null on git clone swallowed all error output — errors are now
shown so authentication failures are diagnosable.
3. No re-run handling — trying to clone into an existing dir silently
failed. Now detects .git, offers git pull instead.
Also: checks for SSH key existence before attempting SSH clone, and prints
actionable guidance (ssh-keygen, ssh-add, ssh -T git@github.com) on failure.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
sky-cam (cameras/non-docker):
Clones outis1one/sky-cam via bootstrap.sh to ~/sky-cam. Prompts for
latitude, longitude, timezone, camera names, BASE_DIR, and optional
Mattermost webhook. Patches sky-cam.conf and installs systemd user
timers via the repo's install.sh. Produces sunrise clips, Four Seasons
timelapse, moon-track, and monthly moon-phase images.
frigate-audio (cameras/docker):
Full stack from outis1one/frigate_w_audio: Frigate 0.17 NVR +
Mosquitto MQTT broker + frigate-notify → ntfy push alerts. Audio-ready
config template with face recognition and LPR pre-configured. Prompts
for camera credentials, media storage path (supports drive detection),
MQTT password (auto-generated), and ntfy server. Bootstraps the
Mosquitto passwd file. Detector choice: CPU / USB Coral / PCIe Coral.
Hardcoded media path from upstream replaced with a configurable prompt.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Adds sync_cc as an extras service module:
- extras/sync_cc.py: the Python tool (3196 lines) — 8 modes: SYNC,
GENERATE, BATCH, RENAME (TMDB), EXTRACT, REMUX, EMBED, BURNSUBS
- services/sync-cc.sh: installs system deps (python3, ffmpeg, mkvtoolnix,
ccextractor), pip installs openai-whisper + ffsubsync, copies the script
to ~/sync-cc/, prompts for TMDB API key → .env, creates /usr/local/bin/sync-cc
wrapper so users run it from any directory containing video/SRT files
Heavy optional deps (easyocr, pgsreader) are installed on first use by the
script itself. GPU (CUDA/MPS) is used automatically if detected.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Three improvements ported from the standalone setupminecraft.sh:
- Whitelist: detect existing whitelist.json on re-run, offer to import
players by number (0=all, comma list, Enter=skip), no UUID re-lookup
for already-resolved entries; new gamertags still looked up via Mojang API
- Vanilla Tweaks: add vanillatweaks.net pre-configured share links at the
top of the download instructions section (datapacks + crafting tweaks)
- Vanilla Tweaks: pause with "Press Enter when datapacks are in
datapacks-download/" so user can SCP the ZIP before the build starts
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Introduces the versioned-snapshot naming convention: each release creates
a new setup_v<X.Y.Z>.sh file alongside the live setup.sh; old snapshots
are never removed. Resets VERSION from 1.0.0 to 0.9.5.
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Every service from ubuntu-post-install-24.04-crowdsec.sh is now a module.
35 services across 8 categories; setup.sh is the primary install path.
- services/linux-to-sync.sh (extras): clone private repo via SSH or PAT
- setup.sh: is_installed case for linux-to-sync (~/.git marker)
- MODULAR.md: migration table updated to show full inventory
- VERSION: 0.9.11 → 1.0.0 (parity achieved)
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Migrate the full media batch from the monolith:
- jellyfin: auto-VAAPI on /dev/dri/renderD128 + render GID; DLNA/discovery UDP ports
- emby: UID/GID baked at install; HW transcoding block commented for manual opt-in
- audiobookshelf: separate audiobooks + podcasts paths; port 13378
- arm: optical drive detection; privileged:true; split movies/music output; port 8080
- lyrion: network_mode:host for Chromecast/Squeezebox UDP discovery; port 9000
- immich: multi-container stack (server+ML+valkey+postgres); two library strategies
(unified with import-photos.sh helper, or external read-only); port 2283
https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
Adds services/silent-send.sh — installs the Silent Send browser extension
(client-side PII redaction for AI chat). Non-docker module: installs git +
Node.js >=18 (NodeSource) + npm, clones outis1one/silent-send to ~/silent-send,
runs npm install (readies web-ext for Firefox build/sign), optionally builds a
signed Firefox .xpi, and prints per-browser load/build instructions. README
written to the checkout.
Introduces a new 'extras' category for non-docker add-ons pulled from other
repos, wired into setup.sh CATEGORY_ORDER (gaming -> extras -> backup) with an
is_installed marker. MODULAR.md groups list updated.
Bumps version to 0.9.9.
Adds services/wolf-pair.sh (gaming group, port 8090). Builds a tiny
python:3.12-alpine container from server.py + Dockerfile (both baked
into the script) that reads Wolf's docker logs for the current pairing
secret and serves a PIN entry form. Runs with network_mode: host so
localhost:47989 (Wolf's /pin/ API) is reachable; docker socket mounted
read-only for log access.
Replaces the ./manage.sh pin CLI workflow: visit the URL, type the PIN.
Optional Caddy subdomain, UFW port 8090, README in ~/docker/wolf-pair/.
Bumps version to 0.9.8.