- joplin: self-hosted sync server (PostgreSQL sidecar, APP_BASE_URL from SITE_DOMAIN)
- stirling-pdf: PDF toolkit with optional Authelia SSO (no built-in auth)
- n8n: workflow automation connecting self-hosted services (WEBHOOK_URL from SITE_DOMAIN)
- changedetection: web page change monitoring with playwright-chrome renderer
- archivebox: personal Wayback Machine, initializes data dir at install time
- calibre-web: ebook library UI with Calibre conversion support (linuxserver image)
- homebox: home inventory and asset management
All services follow the standalone bootstrap pattern and support local/remote Caddy.
README.md updated with new services in appropriate group rows.
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
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
wg-easy: PASSWORD env var removed in v14+; generate bcrypt hash at install
time via 'docker run wg-easy wgpw' and write PASSWORD_HASH instead.
ntfy: write config/server.yml with base-url, cache-file, auth-file, and
behind-proxy:true so push notification links work when behind Caddy.
auth-default-access: deny-all (require topic auth).
mealie: BASE_URL was hardcoded to http://localhost:9925; email links and
OAuth redirects broke when served via Caddy. Now computed from SITE_DOMAIN
and written to .env so it's easy to update.
nextcloud: add OVERWRITEPROTOCOL=https, OVERWRITECLIURL, TRUSTED_PROXIES to
.env so share links and internal redirects use https:// behind Caddy.
onlyoffice: Caddy's default X-Frame-Options: SAMEORIGIN header blocked
OnlyOffice from being embedded as an iframe in Nextcloud. Override it in
the Caddy site block to allow framing.
vaultwarden: remove exposed port 3012 (WebSocket — not needed since v1.29+,
all handled on port 80). Publish port 8888 for direct host access instead.
Remove WEBSOCKET_ENABLED=true (ignored in current versions).
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
These services have no built-in auth. Per CLAUDE.md they should check for
Authelia and offer to protect them with SSO before calling
configure_caddy_for_service. Adds the standard prompt_yn + import authelia
extra block pattern to all three.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
- wolf.sh: add Authelia SSO check, configure_caddy_for_service, write_readme,
and prompt to start Wolf (it had none of these)
- homeassistant.sh: add write_readme with access URL and manage commands
- js99er.sh: add write_readme with access URL and manage commands
- minecraft.sh: add write_readme with manage and backup commands
Completes the service audit — all 49 services now have full interactive setup,
standalone bootstrap, and self-documenting README in the deploy directory.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
lib/common.sh: configure_caddy_for_service now pre-fills the domain prompt
with $DEFAULT_SUBDOMAIN.$SITE_DOMAIN when a site domain has been configured
(setup.sh configure / ~/docker/.config). No more typing the full domain for
every service — just press Enter to accept the default.
services/mattermost.sh: remove redundant custom Caddy/domain block added in
the previous commit. MATTERMOST_SITE_URL is already computed from SITE_DOMAIN
before configure_caddy_for_service is called, so the simple call is sufficient.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Mattermost Calls:
- Add 8443/udp to compose ports for the Calls plugin RTC server (WebRTC
direct path; coturn relay is only the fallback, not the sole path)
- Add 8443/udp to UFW rules and router port-forward table
- Warn that WebRTC requires HTTPS — calls silently fail over HTTP
- Prompt for Caddy domain and update MATTERMOST_SITE_URL in .env to match
the HTTPS URL before Caddy is wired (previously SITEURL was written before
the domain was known, leaving it as http://localhost:8065)
- Update README with RTC server address field and corrected port table
Asterisk web admin:
- No built-in auth: add Authelia SSO check matching CLAUDE.md pattern
- Set WEB_ADMIN_AUTH_DISABLED=true in .env when Authelia handles auth
(prevents double-login prompts)
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
- Replace symlink with real cp for easy-asterisk-v0.10.0.sh: Docker COPY
doesn't reliably follow symlinks; using a real copy is safer.
- Add ./easy-asterisk.sh:/usr/local/bin/easy-asterisk:ro bind mount so the
management script can be updated without rebuilding the image.
- Add TURN_SERVER to .env (empty in LAN-only mode, domain:3478 in FQDN mode)
and reference it in compose instead of building the value inline — fixes
malformed "":3478 in LAN-only mode.
- Add provisioning ports 8088/8089 to UFW rules; these are Asterisk's built-in
HTTP server for Linphone XML provisioning (not the web admin, not Caddy).
- Document in README that Caddy has no role in calls: SIP/RTP use host
networking. Caddy only proxies the web admin (8080). Provisioning ports
(8088/8089) must be accessed directly, not through Caddy.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
vendor/easy-asterisk/: All source files from outis1one/easy-asterisk v0.10.0
vendored so the repo is self-contained — no internet required at install time.
Includes the real Dockerfile (FROM ubuntu:24.04 + full Asterisk stack),
entrypoint.sh (IP detection, TLS cert gen, pjsip/rtp config, web admin),
coturn-entrypoint.sh (robust IP detection wrapper), and the management
script + diagnostic utilities.
services/asterisk.sh: Rewritten to copy from vendor/ instead of downloading
at runtime. Uses the upstream Dockerfile verbatim. Symlinks
easy-asterisk-v0.10.0.sh → easy-asterisk.sh for build context compatibility.
services/onlyoffice.sh: Complete rewrite with correct standalone bootstrap.
_ensure_yq() installs yq v4 automatically (arch-aware). JWT secret is
preserved across re-runs so rotating is explicit. _wire_nextcloud() and
_wire_filebrowser() run on every install invocation (idempotent), skipping
gracefully when containers aren't running rather than failing.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Nextcloud: custom Dockerfile (nextcloud:apache + smbclient) for SMB external
storage support without AIO. All data uses bind mounts so Kopia/Borg coverage
is automatic. Enables files_external app after first boot.
OnlyOffice: JWT-secured document server wired to Nextcloud via occ commands
and FileBrowser Quantum config.yaml if both are installed. Port 8082.
Mattermost: Team Edition + PostgreSQL + dedicated coturn on port 3479 (does
not conflict with Easy Asterisk's coturn on 3478). Bind mounts throughout.
UFW rules and router port-forward instructions printed at install time.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Integrates https://github.com/outis1one/easy-asterisk into the post-install
system. Downloads the management script and coturn entrypoint at install time,
generates docker-compose.yml with host-networking Asterisk + coturn, writes
a randomised TURN password, and opens UFW ports for SIP/RTP/TURN.
Interactive FQDN setup chooses between LAN-only (UDP, no TLS) and FQDN mode
(TLS+SRTP+TURN) and prints required router port-forward instructions.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Apt-based service for Android/iPhone ↔ Linux integration: shared
clipboard, notifications, file transfer, remote input. Works on Ubuntu
(GNOME) and Linux Mint Cinnamon. Opens UFW ports 1714-1764 automatically.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Docker-based Syncthing with PUID/PGID ownership, caddy_net integration,
and standalone bootstrap support. Exposes web UI on 8384 and sync
protocol on 22000 (tcp+udp) and discovery on 21027/udp.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
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.
All 42 applicable service files now support standalone execution.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
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
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
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
dest/current/ stays a plain mirror; deleted/overwritten files are moved to
dest/versions/YYYY-MM-DD/ so accidental deletions are recoverable while
intentional --delete still propagates. Unchanged files in version folders
are hardlinked via --link-dest to avoid extra disk cost. Supports local and
remote (SSH) source/destination paths, saved jobs, and a cron hint.
https://claude.ai/code/session_015SmW4EAD6mMLZGVCygy3GR
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
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
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.
All 42 applicable service files now support standalone execution.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
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
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
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
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
dest/current/ stays a plain mirror; deleted/overwritten files are moved to
dest/versions/YYYY-MM-DD/ so accidental deletions are recoverable while
intentional --delete still propagates. Unchanged files in version folders
are hardlinked via --link-dest to avoid extra disk cost. Supports local and
remote (SSH) source/destination paths, saved jobs, and a cron hint.
https://claude.ai/code/session_015SmW4EAD6mMLZGVCygy3GR
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
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
- Swaps image from filebrowser/filebrowser to gtstef/filebrowser:stable
- Uses ./data:/home/filebrowser/data volume layout (Quantum convention)
- Generates data/config.yaml instead of settings.json + database.db
- Mounts primary path as /files with defaultEnabled: true
- Deploys fbq-add-source.sh for adding extra directories post-install
- Updates README with Quantum-specific instructions
docs: save standalone bootstrap as docs/standalone-template.sh
Preserves the full standalone pattern from filebrowser.sh as the
reference template for adding standalone support to other services.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Previously only edited config.yaml. Now:
- Shows existing volume mounts with host→container paths
- Detects when a host path isn't mounted yet and adds it to compose
- Remove flow optionally removes the volume mount from compose too
- Show displays both compose mounts and config sources side by side
- Uses down/up (not just restart) when compose changes
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Previously only detected the first volume mount, so sources on a
second mount (e.g. /files2) were not reachable. Now lists all mounts
from docker-compose.yml and lets the user pick by number or type a
full container path directly.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Allows editing share path, mount point, and options for an existing
fstab entry. CIFS entries also offer credential update (backs up the
old credentials file before overwriting). Backs up fstab before any
change and offers immediate remount to apply.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
Interactive script to mount network drives and persist them in /etc/fstab:
- SMB/CIFS: prompts for share path, mount point, credentials (saved to
/etc/samba/credentials.<name> at 600/root), SMB version
- NFS: prompts for export path, mount point, NFS version
- Tests the mount before writing fstab
- Backs up /etc/fstab before any edit
- Remove flow: unmounts, removes fstab entry, optionally removes creds file
- Shows currently mounted network shares and fstab entries
- Uses nofail + _netdev so a missing share doesn't block boot
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
(( n++ )) returns exit code 1 when the pre-increment value is 0,
which kills the script under set -euo pipefail. Replace with
n=$(( n + 1 )) which always returns 0.
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt