2 Commits
Author SHA1 Message Date
Claude bec9228c55 Back up existing files before every service overwrites them
Confirmed live: install_frigate()'s fresh-install path overwrote a
working, hand-crafted docker-compose.yml (Frigate + mosquitto +
frigate-notify) with zero backup, because that file's shape didn't match
what frigate.sh's own "existing install" detection knew how to recognize.
Every service's own detection is a judgment call about what counts as
"already installed" and can miss a real setup built outside this repo's
conventions.

lib/common.sh gains backup_if_exists(FILE) — copies FILE to
FILE.bak.<timestamp> if it exists, no-ops otherwise (including DRY_RUN).
Applied before every service's own `cat > docker-compose.yml`/`cat > .env`
write across all 60 services that do one (115 call sites), plus a matching
standalone-mode stub added to every service's own bootstrap block, same
convention already used for port_in_use/find_free_port. This doesn't
replace a service's own update/fresh-reinstall detection — it's the safety
net underneath it, so a wrong detection costs a .bak file to restore from
instead of the original silently disappearing.

Also fixes the actual gap that surfaced this: services/frigate.sh's
Authelia offer only checked for Authelia installed locally on Frigate's
own box, which is never true for a dedicated NVR box with no local Caddy
either (the common shape — Caddy lives elsewhere, snippet-generation mode
already handles that). Now offers Authelia protection unconditionally and,
when Authelia isn't local, asks whether it lives on the same machine as
Caddy (still "import authelia", since that's local to wherever Caddy ends
up) or on a genuinely separate third machine (the explicit
header-pinned forward_auth form, per CLAUDE.md's "forward_auth to a remote
Authelia" note, needed because a bare authelia:9091 shortcut only works
one hop).
2026-08-26 17:26:17 +00:00
Claude 10b985dc95 Add standalone Pi-hole service; move wg-easy's default port off Netbird's
Two independent, requested changes:

- services/pihole.sh: new standalone service, Pi-hole v6 (the image moved
  entirely to a TOML-based /etc/pihole config — the old WEBPASSWORD env var
  and separate /etc/dnsmasq.d volume are both gone; uses
  FTLCONF_webserver_api_password and FTLCONF_dns_listeningMode=ALL
  instead). Deliberately not wired into wg-easy or any other VPN — a device
  has to be pointed at it manually (per-device or via router DHCP). DNS
  itself (53/tcp+udp) is never scanned/moved since shifting it off the
  standard port would defeat the point; a port_in_use check warns instead
  of blocking, since the common case (systemd-resolved on 127.0.0.53 only)
  doesn't actually collide with Pi-hole binding the host's real interfaces.
  Web admin UI is Caddy-fronted like everything else in this repo. Added to
  the README services table.

- services/wg-easy.sh: default VPN/web ports moved from 51820/51821 to
  51830/51831. Netbird's own WireGuard listener also defaults to exactly
  51820 — installing both on one box means wg-easy's existing scan-and-move
  logic would silently shift its port every time, which is harder to
  predict/document than just not starting on the collision in the first
  place. The scan itself is unchanged and still moves both ports further if
  even the new default is taken.

Tested pihole.sh's full standalone install flow (no-Caddy and
Caddy-present-locally cases) against a mocked environment, validating both
generated docker-compose.yml files with `docker compose config`, and
confirmed the reinstall-mode gate correctly no-ops on a second run in
unattended mode.
2026-08-15 02:22:16 +00:00