Commit Graph
10 Commits
Author SHA1 Message Date
Claude d5d979ac31 Add multi-instance support to audiobookshelf, emby, mealie, traccar
Same pattern already established by services/mattermost.sh and
services/wordpress.sh: first instance keeps the plain name/paths/
ports exactly as before (zero behavior change for anyone with a
single instance already installed), and only choosing to add a second
introduces suffixed naming with its own directory, containers, and
ports.

- audiobookshelf.sh, emby.sh, mealie.sh: straightforward -- suffixed
  dir/container name, auto-scanned free host port(s) via `ss`, Caddy
  subdomain default suffixed to avoid collision. emby.sh's existing
  music-only mode is untouched, just correctly parameterized.
- traccar.sh: the harder one -- has its own dedicated Postgres
  container, an autoheal container, and a 150-port device-protocol
  range that can't be scanned port-by-port. Additional instances shift
  the whole range by 1000 (6000-6150, 7000-7150, ...) based on how
  many traccar/traccar-* directories already exist, which never lands
  on Asterisk's fixed ports the way the first instance's range does,
  so no exclusions are needed there. Also scoped the autoheal label
  per-instance (autoheal-traccar-<suffix>) -- autoheal watches by
  Docker label host-wide, not scoped to a compose project, so two
  instances sharing the generic "autoheal" label would each try to
  manage the other's container too.

Found and fixed two real bugs via testing before committing, not just
code review:
- The device-protocol range offset counted existing instances via
  `find $DOCKER_DIR -maxdepth 1 -name 'traccar*'`, which also matches
  $DOCKER_DIR itself if its own basename happens to start with
  "traccar" (true in my test harness, structurally possible in real
  use too) -- fixed with -mindepth 1.
- Verified port auto-scanning actually detects a simulated in-use
  port and increments past it, using a stateful fake `ss` rather than
  trusting the logic by inspection alone.

Verified end-to-end for all four: first instance unchanged from prior
behavior, second instance gets fully distinct dir/containers/ports,
and (traccar specifically) correct DB container, correctly-scoped
autoheal label, and correct shifted port range in the generated
compose file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBtExJcqxnokyZZKmphdug
2026-08-09 21:57:23 +00:00
Claude 7a66ef2e2f emby: add music-only setup mode with per-user library access guidance
Prompts whether this install is music-only (changes the default folder
to ~/music and the prompt wording — Emby has no compose/env flag for
"music-only", library types are chosen in its own web setup wizard, so
this is guidance plus a sane default, not a functional restriction).
Generated README walks through adding only a Music library and, the
actual reason to pick Emby for this role over Lyrion, per-user library
access under Dashboard → Users → Access — LMS/Lyrion has no equivalent,
just one shared server-wide password.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBtExJcqxnokyZZKmphdug
2026-08-09 18:07:09 +00:00
Claude 1fc0a6edfe Apply the local/remote Caddy mode resolution to every service, not just traccar
traccar.sh's caddy_net wiring was fixed to mirror configure_caddy_for_service's
own mode resolution (CADDY_MODE from site config, then a local ~/docker/caddy,
then the legacy CADDY_REMOTE_HOST var) instead of only checking for the local
directory. That same bare directory check was copy-pasted into the caddy_net
wiring of every other Docker service in the repo, so a site with Caddy on a
different box would silently fail to join any of their containers to caddy_net
during setup (or, for homeassistant/koha, only get half the wiring right).

Applied the same fix mechanically across all 37 services using the standard
_CADDY_NET_BLOCK/_CADDY_NET_SECTION pattern (verified identical text via
scripted diff before touching any of them), plus by hand for:
- homeassistant.sh and koha.sh, which use their own differently-shaped
  variables (HA_CADDY_NET_LINES / _CADDY_NET_ENTRY) for the same decision
- paintplus.sh and ai-stack.sh, which do a live `docker network connect`
  instead of a compose network block
- watchyourlan.sh, whose Caddy note was worded for local-only setups

sms-inbound.sh got more than a mode swap: its Caddy wiring was hand-rolled
(not routed through configure_caddy_for_service) and had no remote-Caddy
path at all — a remote Caddy box would get a misleading "Caddy isn't
installed here" message instead of a snippet. Added
_sms_write_caddy_snippet(), mirroring the snippet-file pattern
configure_caddy_for_service uses everywhere else, and pointed the firewall
gate at the same three-way mode instead of a two-way dir check.

Verified: bash -n across all of services/*.sh, a scripted check that every
touched file has exactly one _CADDY_MODE resolution and no leftover bare
`[ -d "$DOCKER_DIR/caddy" ]` feeding a caddy_net decision, and spot-checked
docker compose config renders (traccar, mattermost) confirming the ${VAR}
interpolation and multi-service usage sites still resolve correctly.
2026-08-03 18:54:02 +00:00
Claude fa906186c3 fix(services): conditional caddy_net across all Docker service scripts
Only include the caddy_net network block in generated docker-compose.yml
files when ~/docker/caddy exists. Prevents "network caddy_net declared
as external, but could not be found" on standalone installs without Caddy.

Affected: actualbudget, archivebox, arm, audiobookshelf, calibre-web,
changedetection, drum-rhythm-game, emby, fmd, frigate, frigate-audio,
frigate-notify, gatus, homeassistant, immich, iopaint, jellyfin, joplin,
koha, lyrion, magicmirror, mail-archiver, mattermost, mealie, meshcentral,
n8n, nextcloud, ntfy, onlyoffice, portainer, stirling-pdf, syncthing,
traccar, unifi, uptimekuma, vaultwarden, wg-easy

Skipped: authelia (creates caddy_net itself), caddy, crowdsec, wolf,
wolf-pair, and services using network_mode: host with no caddy_net.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-20 04:16:41 +00:00
Claude ec3f9bfd3f Add remote Caddy support — generate snippet files when Caddy is on another host
New site config key: CADDY_REMOTE_HOST (set via 'sudo ./setup.sh configure').
When set, configure_caddy_for_service operates in "remote" mode instead of
writing to a local Caddyfile:
- Upstream uses CADDY_REMOTE_HOST:PORT (host IP, not container name)
- Snippet saved to ~/docker/caddy-snippets/<subdomain>.caddy
- User is shown scp/rsync commands to copy it to the Caddy machine

Three modes in configure_caddy_for_service (lib/common.sh and inline stubs):
  local:  ~/docker/caddy/ exists → write Caddyfile + reload (existing behavior)
  remote: CADDY_REMOTE_HOST set → save snippet, print copy instructions
  none:   neither configured → silent return (unchanged)

All 31 service standalone bootstrap stubs updated with the new logic.
CADDY_REMOTE_HOST global added to all 42 standalone bootstrap sections.
setup.sh configure now prompts for CADDY_REMOTE_HOST with a clear explanation.
wolf.sh: add missing stubs (configure_caddy_for_service, write_readme,
  prompt_yn, ensure_docker_dir_ownership) and the Authelia/Caddy/start calls
  that were missing from the install function.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-09 00:28:30 +00:00
Claude 4b7a2c050b services: add standalone bootstrap to crowdsec, ddclient, emby, fmd, frigate-audio, frigate-notify
Each service can now be run directly with sudo bash <service>.sh on any
machine with Docker installed, without needing the full post-install repo.
Uses the shared bootstrap pattern from docs/standalone-template.sh.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 17:01:35 +00:00
Claude 9c52ac22e1 Fix Caddy routing: use container:port via caddy_net (DoTheEvo pattern)
Undo the host.docker.internal approach from the previous commit — proper
Docker networking routes Caddy to services by container name on the shared
caddy_net, not via the host gateway.

- lib/common.sh: configure_caddy_for_service now accepts either a plain
  port number (localhost:PORT fallback) or container:port (preferred).
  The Caddyfile entry uses the container name for direct Docker DNS routing.
- services/caddy.sh: remove extra_hosts hack; update Caddyfile template
  comments to show container_name:port format
- All service files: update configure_caddy_for_service calls to pass
  container_name:internal_port (e.g. "filebrowser:80", "mealie:9000").
  Services using network_mode:host keep plain port numbers.
- tools/manage_users.sh: new FileBrowser user-management script (deployed
  to ~/docker/filebrowser/ during installation). Manages users via the
  FileBrowser REST API: list, add, delete, passwd, scope, info commands.
  Documents username format (letters/numbers/hyphens/underscores),
  password rules (min 8 chars, letter + number required), and scope path
  convention relative to /srv (= FB_PATH on the host).

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 22:12:01 +00:00
Claude 56bec03c9b Fix Caddy routing and add caddy_net to all Docker services
- lib/common.sh: fix broken reverse_proxy target — localhost inside Caddy's
  container is the container's own loopback, not the host; change to
  host.docker.internal so proxied ports are actually reachable
- services/caddy.sh: add extra_hosts host.docker.internal:host-gateway so
  the above resolves correctly; create caddy_net bridge network in Caddy's
  own compose so other services can reference it as external; update all
  Caddyfile template comments and README examples to match
- services/filebrowser.sh: update image tag from deprecated :s6 to :latest;
  remove non-functional PUID/PGID env vars (filebrowser/filebrowser does not
  honour them); add configure_caddy_for_service call; add caddy_net
- services/ntfy.sh: add configure_caddy_for_service call; add caddy_net
- services/portainer.sh: add configure_caddy_for_service call; add caddy_net
- services/frigate-notify.sh, watchtower.sh: add caddy_net for
  container-to-container comms (frigate, ntfy) without a Caddy call
- All remaining web-facing Docker services: add caddy_net network block to
  docker-compose and CADDY_NET to .env where applicable; services using
  network_mode: host (wolf-pair, lyrion) have the top-level block only

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 22:02:26 +00:00
Claude 56d2f9e85b Add site-wide defaults: timezone, domain, Caddy network
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
2026-06-03 22:13:59 +00:00
Claude a36f058a51 feat(media): add 6 media service modules (v0.9.10)
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
2026-06-03 18:24:02 +00:00