Commit Graph
233 Commits
Author SHA1 Message Date
Claude f1631d8cb7 Add tools/rsync-backup.sh — interactive rsync mirror backup with versioned deletes
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
2026-06-08 16:15:19 +00:00
Claude a80eef0984 services: replace FileBrowser with FileBrowser Quantum
- 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
2026-06-08 15:37:52 +00:00
Claude eab374978e tools: fbq-add-source.sh — manage compose volume mounts + config.yaml together
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
2026-06-08 14:29:00 +00:00
Outis 0035fd3597 Merge pull request #72 from outis1one/claude/zealous-feynman-odDrh
Claude/zealous feynman od drh
2026-06-08 09:53:15 -04:00
Claude a1a88c2821 tools: fbq-add-source.sh — support multiple volume mounts
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
2026-06-08 13:52:14 +00:00
Claude 6133721af7 tools: remove readOnly from fbq-add-source.sh — not a valid Quantum config field
Quantum's YAML parser rejects 'readOnly' under source config with
'unknown field'. Removed the prompt, the written field, and the
display column entirely.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 13:35:32 +00:00
Outis dd563e28d3 Merge pull request #71 from outis1one/claude/zealous-feynman-odDrh
tools: add edit mount option to mount-network-drive.sh
2026-06-08 09:29:33 -04:00
Claude 653963da08 tools: add edit mount option to mount-network-drive.sh
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
2026-06-08 13:28:00 +00:00
Outis 259fc48047 Merge pull request #70 from outis1one/claude/zealous-feynman-odDrh
tools: add mount-network-drive.sh for SMB/CIFS and NFS shares
2026-06-08 09:16:41 -04:00
Claude 06a163614d tools: add mount-network-drive.sh for SMB/CIFS and NFS shares
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
2026-06-08 13:13:15 +00:00
Outis f752ef82cb Merge pull request #69 from outis1one/claude/zealous-feynman-odDrh
Claude/zealous feynman od drh
2026-06-08 08:44:32 -04:00
Claude 838af715aa tools: fix fbq-add-source.sh exiting after first source with set -e
(( 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
2026-06-08 12:43:42 +00:00
Claude 97e6fa25ed tools: change fbq-add-source.sh quit option from 4 to 0
https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 12:40:52 +00:00
Outis 1f156016d5 Merge pull request #68 from outis1one/claude/zealous-feynman-odDrh
tools: fix fbq-add-source.sh failing to list sources with inline yaml…
2026-06-08 08:39:46 -04:00
Claude 6030c8b06d tools: fix fbq-add-source.sh failing to list sources with inline yaml comments
yq stops mid-array when it encounters inline comments like
'# grant per-user only'. Strip comments via sed before piping
to yq in list_sources, source_exists, and before in-place edits.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 12:37:57 +00:00
Outis 364d81fa9b Merge pull request #67 from outis1one/claude/zealous-feynman-odDrh
tools: fix null display in fbq-add-source.sh for sources without name…
2026-06-08 08:35:19 -04:00
Claude 5af33a9ebb tools: fix null display in fbq-add-source.sh for sources without name/config
Sources added manually without a name or config block showed "null"
for name and readOnly. Use yq // operator to fall back to sensible
defaults: "(unnamed)" for missing name, false for missing booleans.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 05:32:10 +00:00
Outis 3f352debb0 Merge pull request #66 from outis1one/claude/zealous-feynman-odDrh
Claude/zealous feynman od drh
2026-06-08 01:27:37 -04:00
Claude 99e8671110 tools: simplify fbq-add-source.sh — config.yaml only, no compose edits
Assumes the parent data directory is already broadly mounted in
docker-compose.yml so subdirectories are already inside the container.
Script now only edits config.yaml and restarts the container — no
docker-compose surgery needed per new source.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 05:20:41 +00:00
Claude 7379f0b62f tools: add fbq-add-source.sh for FileBrowser Quantum source management
Interactive script that keeps docker-compose.yml and config.yaml in sync
when adding or removing file sources in a FileBrowser Quantum installation.

- Prompts for host path, source name, defaultEnabled, readOnly
- Validates against duplicate volume mounts and source entries
- Backs up both files before editing
- Uses yq v4 for safe YAML editing (no fragile sed/awk on YAML)
- Offers container restart after changes
- Works standalone; no post-install framework dependency

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 04:59:11 +00:00
Outis fd73220a05 Merge pull request #65 from outis1one/claude/zealous-feynman-odDrh
Claude/zealous feynman od drh
2026-06-08 00:07:44 -04:00
Claude 9cae430166 additional_directories.sh: fix nested bind-mount problem properly
Root cause: user scopes inside /data/... (the main data bind-mount) mean
any extra mount would nest inside another bind-mount — Docker does not
reliably layer these, so directories appeared in `ls` but were empty
and FileBrowser returned 404.

Fix: detect nested scopes and migrate them to the named volume (fb_users)
before adding any extra mounts.

Migration flow:
- Detects scope is inside /data bind-mount
- Suggests a new scope path in the named volume (e.g. /alice)
- Creates the scope directory via docker exec (no host-side clutter)
- Offers to mount the user's personal files dir as my-files/
- Updates the user's scope in FileBrowser via API PUT /api/users/:id
- Then adds requested extra dirs as non-nested bind-mounts

Also added: let user choose the display name for each added folder
(e.g. mount audiobookshelf but show it as "audiobooks").

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 04:02:03 +00:00
Claude 6d0d72bef5 additional_directories.sh: create host mount-point dirs for nested mounts
When a user's FileBrowser directory lives inside an existing bind-mount
(e.g. /srv/data/users/alice), Docker needs an empty directory at the
host-side equivalent path before it can overlay an inner bind-mount on
top of the outer one.  Without it the inner mount silently fails and
the extra folder never appears.

Now creates the mount-point directory on the host automatically before
adding the compose entry, with a visible note so the user knows a dir
was created.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 03:46:21 +00:00
Outis fef496c364 Merge pull request #64 from outis1one/claude/zealous-feynman-odDrh
filebrowser: replace manage_users.sh with additional_directories.sh
2026-06-07 23:31:57 -04:00
Claude 412560aa8f filebrowser: replace manage_users.sh with additional_directories.sh
Symlinks don't work for giving scoped FileBrowser users access to extra
folders — FileBrowser's afero.BasePathFs blocks symlinks that resolve
outside the user's scope directory.

Switch to bind-mount approach: additional_directories.sh edits
docker-compose.yml to add real bind-mount entries for each extra folder,
so FileBrowser sees them as actual subdirectories within the user's root.
No symlinks, no scope-boundary issues.

Features:
- Reads FB_PATH from .env to list available source folders on the host
- Parses docker-compose.yml to show what's already configured per user
- Adds/removes volume entries with a timestamped backup before each edit
- Prompts to restart the container after changes
- Normalises scope paths from the API (handles missing leading slash)

manage_users.sh removed — user CRUD is handled by the FileBrowser web UI.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 03:29:36 +00:00
Outis af19475f44 Merge pull request #63 from outis1one/claude/zealous-feynman-odDrh
Claude/zealous feynman od drh
2026-06-07 23:19:16 -04:00
Claude c72a20af42 manage_users.sh: strip to directory-access-only tool
Removed all user CRUD (add, delete, rename, passwd, scope change).
The FileBrowser web UI handles those. Script is now focused solely
on adding/removing extra folder shortcuts for users who have a
restricted root directory. Simpler menu, ~half the code.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 03:06:52 +00:00
Claude 2e63ca1756 caddy: document internal vs host port in Caddyfile template and README
Services on caddy_net talk container-to-container using the internal
port. The host-mapped port (left side of ports:) is only for direct
access from another machine. Added this as a comment block in the
generated Caddyfile starter and in the README.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 02:57:12 +00:00
Outis 7d0a26fc8a Merge pull request #62 from outis1one/claude/zealous-feynman-odDrh
Claude/zealous feynman od drh
2026-06-07 22:33:28 -04:00
Claude c2df116a72 manage_users.sh: don't auto-create user dir, rename scope→directory
- Remove silent mkdir -p when adding extra directories. If the user's
  directory doesn't exist in the container, ask before creating it.
  This avoids creating folders the admin didn't intend.

- Rename all user-facing "scope" text to "directory" throughout:
  prompts, banners, menu labels, column headers, help text, error
  messages. The FileBrowser API field is still called "scope"
  internally, and the CLI subcommand name stays "scope" for compat.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 02:30:53 +00:00
Claude 39c85326e6 filebrowser: named volume for user dirs, rename linked→additional dirs
docker-compose now uses two separate mounts:
  fb_users named volume → /srv      (user home dirs + shortcuts, Docker only)
  FB_PATH bind mount    → /srv/data (actual files, unchanged on host)

User dirs and their shortcuts live entirely in the Docker named volume —
they persist across reboots but never appear on the host filesystem.
Full-access scope is /data; per-user scopes are /alice etc.

manage_users.sh:
- Detect layout: get_data_root() returns /srv/data (new) or /srv (legacy)
  so the script works with both old and new installs automatically
- "Linked directories" renamed to "additional directories" throughout
  (menu labels, prompts, error messages, usage text)
- prompt_add_links → prompt_add_dirs, menu_links → menu_add_dirs
- Available-folder listing and symlink targets use get_data_root()
- Scope examples updated to show /data for full access (new layout)
- Don't offer additional directories when scope is /data (full access)

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 02:23:07 +00:00
Claude 659b3924c0 fix manage_users.sh: strip fields that cause 400 on newer FileBrowser
Removed dateFormat, hideDotfiles, singleClick, and sorting from the
POST /api/users payload — FileBrowser rejects them as invalid data
types on some versions. Only stable fields are now sent.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 01:25:15 +00:00
Outis 9613031341 Merge pull request #61 from outis1one/claude/zealous-feynman-odDrh
fix manage_users.sh: show API errors on user creation, fix symlink li…
2026-06-07 21:16:03 -04:00
Claude d591f38acf fix manage_users.sh: show API errors on user creation, fix symlink listing
- User creation was silently failing: api_post used curl -sf (fail on
  HTTP error) with output piped to /dev/null, so set -Eeuo pipefail
  would exit the script with no message. Now captures HTTP status code
  and response body, printing the server's error message on failure.

- Symlink folder listing (? prompt) only searched -type d, missing
  symlinked directories in /srv. Changed to -type d -o -type l so
  all browsable entries appear. Also switched xargs echo to tr for
  a cleaner one-line display.

- mkdir -p and ln -s in docker exec were not checked for errors;
  failures would silently kill the script under set -e. Both now
  show a useful error message and continue/return instead of crashing.

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-08 01:12:43 +00:00
Outis 8f1efe5003 Merge pull request #60 from outis1one/claude/clever-mayer-FvxF6
filebrowser.sh: full Caddy config in standalone stub (not just info msg)
2026-06-07 21:07:10 -04:00
Claude 956c13e723 filebrowser.sh: full Caddy config in standalone stub (not just info msg)
Replace the "configure manually" stub with a real implementation that
matches common.sh's configure_caddy_for_service behaviour:
- Prompts to configure (skippable)
- Asks for domain with example hint
- Backs up Caddyfile before writing
- Checks for duplicate domain entry, offers overwrite
- Appends site block with reverse_proxy, security headers, JSON log
- fmt + reload via docker exec caddy caddy fmt/reload

Used when filebrowser.sh is run standalone without the repo present.
When the repo is present (common.sh sourced), the real function is used.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-08 00:54:15 +00:00
Outis 53a64aaa1a Merge pull request #59 from outis1one/claude/clever-mayer-FvxF6
filebrowser.sh: fix DOCKER_DIR pointing to /root when run with sudo
2026-06-07 20:47:16 -04:00
Claude c005e01156 filebrowser.sh: fix DOCKER_DIR pointing to /root when run with sudo
DOCKER_DIR was computed before ACTUAL_HOME, so $HOME resolved to
/root (the root user's home) instead of the invoking user's home.
Files were created under /root/docker/ rather than ~/docker/.

Fix: compute ACTUAL_USER and ACTUAL_HOME first, then DOCKER_DIR.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-08 00:42:13 +00:00
Outis 35f7d0a843 Merge pull request #58 from outis1one/claude/clever-mayer-FvxF6
filebrowser.sh: support standalone execution (sudo bash filebrowser.sh)
2026-06-07 20:32:14 -04:00
Claude 9641bebda8 filebrowser.sh: support standalone execution (sudo bash filebrowser.sh)
Add standalone bootstrap block at the top (BASH_SOURCE[0] == $0 guard):
- If lib/common.sh is present (repo cloned), source it — gets real helpers
  and picks up any existing ~/docker/.config site settings automatically
- If not (one-off copy), inline minimal stubs: logging, require_docker
  (checks Docker is installed, gives install hint if not), prompt_text/yn
  (match common.sh eval pattern so install_filebrowser locals work),
  configure_caddy_for_service (no-op with manual hint), write_readme
- Sets DOCKER_DIR, ACTUAL_USER, SITE_TZ etc. with sensible defaults
- register_service becomes a no-op (no wizard menu to register into)
- Execution deferred via _RUN_STANDALONE flag to after function definition

Still works identically when sourced by setup.sh — the bootstrap block
is skipped entirely in that path.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-08 00:27:15 +00:00
Outis 925e8f4f05 Merge pull request #57 from outis1one/claude/clever-mayer-FvxF6
manage_users.sh: fix login silently bailing on credential entry
2026-06-07 20:08:34 -04:00
Claude 9ab7979833 manage_users.sh: fix login silently bailing on credential entry
Three fixes in ensure_token:
- Use jq to build the login JSON so special chars in passwords
  (quotes, backslashes, etc.) don't break the raw string interpolation
- Add || true to the curl call so set -e doesn't silently exit on
  connection refused before the response check runs
- Show FileBrowser's actual response on failure so the user can see
  whether it's wrong credentials vs unreachable vs something else

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-08 00:06:21 +00:00
Outis 38b24481f5 Merge pull request #56 from outis1one/claude/clever-mayer-FvxF6
Claude/clever mayer fvx f6
2026-06-07 19:59:30 -04:00
Claude ea1a9cf3b7 manage_users.sh: list folders on demand with ? instead of auto-display
Auto-displaying all top-level dirs could be a wall of text.
Typing ? at the folder prompt lists them on demand instead.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:27:54 +00:00
Claude c71c08ac87 manage_users.sh: show available folders before link prompt
List top-level directories from /srv so the user knows what to type
without having to guess. Subdirs (e.g. documents/shared) still work.
Skip link prompt when scope is / (user already has full access).

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:22:22 +00:00
Claude c584811be4 manage_users.sh: remove /srv from all user-facing prompts
Users think in FileBrowser folder names, not container paths.

- prompt_add_links: prompt now "Folder to add [done]:" with examples
  like "music  photos  documents/shared" — /srv added internally
- list_links: strip /srv prefix from displayed target paths
- menu_links: rename options to "Add folders" / "Remove a folder"
- scope prompts: remove the leading "/" hint (confusing); normalise
  internally instead
- ok message shows "(from path/subdir)" only when link name differs

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:18:50 +00:00
Claude 5fdeff3f9a manage_users.sh: inline link prompts on add/scope-change
- prompt_add_links: shared helper loops asking for /srv paths until
  blank Enter, creates symlinks via docker exec, skips bad paths
- cmd_add: offers linked-dir prompt right after user creation
- cmd_scope: offers linked-dir prompt after a scope change
- menu_links: tighter submenu (list + add loop + remove) replacing
  the old menu_symlinks; called from Modify option 5
- Scope prompts now show the leading / so the user only types the rest
- Note on delete: symlinks on disk survive user deletion (by design)

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:15:12 +00:00
Claude b884d79dd2 manage_users.sh: add linked-directory (symlink) management
New option 5 in the Modify submenu: "Manage linked directories"

- Lists existing symlinks inside the user's scope dir (via docker exec)
- Add: prompts for source path (/srv/...) and a display name, creates
  the symlink inside /srv<scope>/<name> → /srv<source> in the container
- Remove: lists links, prompts for name, refuses to delete non-symlinks
- Warns if source path doesn't exist yet; offers to create anyway
- Auto-detects container name from docker-compose.yml next to the script
- Checks that the container is running before any docker exec calls

This is the recommended workaround for FileBrowser's single-scope
limitation: symlinks inside the scope dir appear as normal folders.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 23:07:27 +00:00
Claude 141c9115a7 Rewrite manage_users.sh: add interactive menu, fix password nameref bug
- Interactive menu when run with no args (login once, reuse token)
- Modify submenu: change username, password, scope, or toggle admin
- Fix: prompt_password now uses local -n nameref (bash 4.3+) so the
  caller's local variable is actually set; printf -v was writing to
  global scope and being shadowed by the caller's local declaration
- One-shot commands unchanged: list/add/delete/passwd/scope/rename/info
- FileBrowser only supports one scope per user — documented clearly

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 22:52:42 +00:00
Claude 774f6ad561 Add 6 new utility services: gatus, mail-archiver, rustdesk, unifi, vaultwarden, watchyourlan
- gatus: status/uptime monitoring page with hot-reloaded config
- mail-archiver: IMAP email archive and full-text search (postgres backend)
- rustdesk: self-hosted remote desktop relay, cross-VLAN/FQDN docs
- unifi: UniFi Network Application with MongoDB init via Docker configs
- vaultwarden: Bitwarden-compatible password manager with SMTP prompts
- watchyourlan: network device tracker (host networking for ARP scanning)

All follow caddy_net container-routing pattern except rustdesk (raw TCP/UDP)
and watchyourlan (network_mode: host, incompatible with caddy_net).

README.md services table updated with all 6 new entries.

https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29
2026-06-07 22:32:44 +00:00