Commit Graph
15 Commits
Author SHA1 Message Date
Claude 516e0db66f asterisk.sh: same port-exposure fix and UFW enable as the DO edition
Mirrors the fixes just made in asterisk-digital-ocean.sh:

- Reordered so the Caddy reverse-proxy decision happens before the
  UFW rules are built, using the new CADDY_SERVICE_CONFIGURED/
  CADDY_SERVICE_MODE signal from configure_caddy_for_service() to
  skip opening the web admin port on the LAN when a local Caddy is
  already fronting it (still opens it for a remote Caddy machine,
  which needs LAN access to reach this host directly).
- Calls the new ensure_ufw_enabled() so UFW actually enforces the
  rules this script adds, instead of leaving them queued but inert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015X1jRGHwrvovz2qkhKfDZi
2026-07-20 18:20:30 +00:00
Claude 8ee35e1995 Add prompt_reinstall_mode helper and document the update/fresh/cancel convention
Replaces the y/n "update in place?" prompt in asterisk.sh/asterisk-do.sh
with an explicit r/f/c choice — (r)einstall in place, (f)ull install,
(c)ancel — defaulting to cancel on a bare Enter (or Ctrl-D) instead of
falling through to a destructive full reinstall.

Adds prompt_reinstall_mode to lib/common.sh (plus matching standalone
stubs in both asterisk scripts for when they run without the full repo)
and documents the convention in CLAUDE.md: any service with a persistent
install directory should offer this choice on rerun instead of re-asking
every prompt just to pick up a script fix.
2026-07-20 01:23:22 +00:00
Claude 0d719a5cad Add update-in-place mode to asterisk and asterisk-do installers
Re-running either installer on an existing install used to re-ask
every prompt (domain, extras, firewall, Authelia) just to pick up a
script fix like the exports mount. Both now detect an existing
docker-compose.yml + .env and offer to update in place instead: only
vendor files and docker-compose.yml are refreshed and the stack is
rebuilt, leaving .env, firewall rules, and Caddy/Authelia config
untouched.

The vendor-copy and docker-compose.yml generation blocks (previously
inline and duplicated between what would have been two near-identical
code paths) are factored into per-file helper functions
(_asterisk_do_refresh_vendor_files/_asterisk_do_write_compose and
_asterisk_refresh_vendor_files/_asterisk_write_compose) so fresh
installs and updates share one copy of the logic instead of drifting
apart — the same problem that caused the /root export path and the
vpn-diagnostics.sh COPY bug to slip through unevenly between the two
services in the first place. Names are per-file since setup.sh sources
every services/*.sh into one process.
2026-07-20 01:13:51 +00:00
Claude 21f8e0e096 Persist Easy Asterisk client exports to the docker directory
The vendor easy-asterisk script hardcodes /root for both export output
and its import file listing, but nothing was mounted there — exports
were being written to the container's ephemeral filesystem and lost on
recreate. Bind-mount ./exports to /root in both asterisk.sh and
asterisk-do.sh so exports/imports land under ~/docker/<service>/exports
on the host.
2026-07-20 01:02:37 +00:00
Claude cb8ff3f4f0 Fall back to a Caddy restart when reload fails (admin API is off)
Confirmed on a real deployment: the template Caddyfile ships with
"admin off" (deliberate — no local API attack surface), which means
`caddy reload` can never work, since it depends on that same admin
endpoint. Every Caddyfile-editing code path was silently failing to
apply changes as a result — `docker logs caddy` showed
"admin endpoint disabled" and the reload command errored, but the
Caddyfile edit itself (which doesn't need the admin API) had already
succeeded, leaving the running config stale until something else
happened to restart the container.

Fixed in the two places that actually matter here: lib/common.sh's
configure_caddy_for_service (used by asterisk.sh and most other
Caddy-fronted services in the full repo) and asterisk-do.sh's own
self-contained Caddy block (both the standalone-bootstrap stub and the
main path). Each now tries the lightweight reload first — harmless,
and still works if a box ever has the admin API enabled — then falls
back to `docker restart caddy` if that fails, rather than leaving an
edited-but-unapplied Caddyfile.

Not fixed: the same duplicated pattern in ~35 other service files that
carry their own standalone-bootstrap copy of this logic. Those only
matter for the rare single-file standalone execution path for each of
those specific services and are unrelated to tonight's actual issue —
out of scope here.

Verified: full regression run on both asterisk.sh and asterisk-do.sh
still completes cleanly end to end.
2026-07-19 17:43:52 +00:00
Claude 4af9cfeae3 Auto-scan for a free web admin port instead of hardcoding one
The 8080->8081 fix from the last commit just moved the collision
risk, not removed it — any hardcoded port can eventually collide with
something else on a box running several services. Both services now
scan for the first genuinely free port starting at 8081 (ss -tlnH
"sport = :$PORT", capped at 100 ports checked) and use whatever they
find — .env, UFW, the DO Cloud Firewall rule, and the Caddy proxy
target all follow the actual chosen port, not a fixed number.

asterisk-do.sh's self-contained Caddy block (unquoted heredoc) reads
the port live. asterisk.sh's README heredoc is quoted (no expansion),
so its generated docs keep the static "8081" default with an added
note to check .env for the real value if it differed — the summary
echo outside that heredoc still reports the live value correctly.

Verified: normal case still lands on 8081; with 8081 deliberately
occupied by another process, both services correctly detect the
collision and fall through to 8082 instead, confirmed via the actual
generated .env in each case.
2026-07-19 17:20:56 +00:00
Claude 2483365141 Fix web admin/CrowdSec port collision: default WEB_ADMIN_PORT to 8081
Real-world failure: CrowdSec's Local API listens on 127.0.0.1:8080 by
default (confirmed against its actual upstream config.yaml), and Easy
Asterisk's web admin also defaults to 8080. Both services in this repo
run with network_mode: host / directly on the host, so whichever one
starts second gets "OSError: [Errno 98] Address already in use" — in
this case CrowdSec (started earlier via the auto-install chain) had
already claimed the port before the web admin tried to start.

Moved the web admin's default to 8081 in both asterisk-do.sh and
asterisk.sh — WEB_ADMIN_PORT in .env, the UFW rule, the DO Cloud
Firewall rule, the Caddy reverse_proxy target, and every doc/summary
reference. 8081 doesn't collide with anything else in either stack
(5060/5061/8088/8089/3478/10000-20000/49152-49252) or with CrowdSec's
LAPI (8080) or Prometheus metrics (6060, localhost-only either way).

Left the vendor files' own internal fallback (WEB_ADMIN_PORT:-8080)
untouched — .env's explicit value overrides it at runtime regardless,
and vendor/ stays pristine per this repo's convention.

Verified: no stray 8080 in any generated .env/docker-compose.yml for
either service after a full install run; the vendor files' own
internal 8080 fallback (never applies here, since .env always sets it
explicitly) is the only remaining occurrence anywhere.
2026-07-19 16:51:50 +00:00
Claude edf9c7ee25 Fix Docker build failure: copy vendor's scripts/ directory
The Dockerfile COPYs scripts/vpn-diagnostics.sh and
scripts/dns-whitelist.sh into the image, but the vendor-file-copying
step in both asterisk.sh and asterisk-do.sh never copied (or
downloaded, in the GitHub-fallback branch) that scripts/ directory —
only Dockerfile, entrypoint.sh, coturn-entrypoint.sh, and the
management script. Every real install hit "docker compose up -d
--build" failing with:

  failed to compute cache key: ... "/scripts/dns-whitelist.sh": not found

Confirmed live on a deployed droplet. vendor/easy-asterisk/scripts/
already has both files — this was purely a missed copy step, not a
vendoring gap. Fixed in both files identically (mkdir scripts/, copy
or curl both scripts, chmod +x alongside the existing executables).

Verified at the filesystem level: after a full install run, both
files land in the build context with correct executable permissions,
resolving the exact COPY instructions that were failing. Full
docker build verification wasn't possible in this sandbox (a separate,
unrelated network restriction blocks pulling the ubuntu:24.04 base
image here), but the missing-file root cause is directly fixed.
2026-07-19 16:03:48 +00:00
Claude 225e277abb asterisk: default to FQDN mode, auto-detect VLANs, auto-sync Caddy certs
Defaults install_asterisk() to FQDN networking mode and prompts for VLAN/VPN
subnets (with host-network auto-detection to filter out noise like Docker
bridges) so phones on other networks get correct NAT/SDP handling from the
first boot.

The container now mounts Caddy's cert store read-only when Caddy is
installed, and the entrypoint syncs a matching Let's Encrypt cert for
DOMAIN_NAME automatically, re-checking every 12h to pick up renewals without
a restart. Falls back to self-signed only when no matching cert is found.

Also fixes a real bug hit in the field: a preserved/migrated pjsip.conf could
be missing the transport-udp/transport-tcp sections entirely, with no bind
error logged, silently blocking any device that registers without TLS. Adds
the same migration-injection already used for transport-tls.
2026-07-01 17:19:57 +00:00
Claude ec9aa605cf Fix named volumes in koha/asterisk for backup coverage; add Koha setup wizard
koha.sh:
- Replace named volume `koha_db_data` with bind-mount `./data:/var/lib/mysql`
  so the MariaDB database is inside ~/docker/koha/ and covered by backup.sh
- Add interactive setup wizard: collects library name, code, admin credentials,
  item types (with custom additions), and shelf locations before first start
- Generate ~/docker/koha/post-setup.sh at install time; after completing the
  web installer the user runs it to auto-configure the library branch, item
  types, shelf locations, and system preferences via the Koha REST API
- Updated README with exact step-by-step web installer instructions and
  admin password prominently displayed

asterisk.sh:
- Replace all 5 named volumes (asterisk-config, easy-asterisk-config,
  asterisk-logs, asterisk-spool, asterisk-lib) with bind-mounts inside
  ~/docker/asterisk/ so all config and state is covered by backup.sh
- mkdir -p for all bind-mount dirs before compose up
- Replace SSH-based standalone configure_caddy_for_service stub with the
  snippet approach used everywhere else (local Caddy writes Caddyfile;
  remote Caddy via VPN/Netbird saves ~/docker/caddy-snippets/<name>.caddy)

https://claude.ai/code/session_01S7UecmQRG6CKTYPoBqbVLj
2026-06-09 18:39:27 +00:00
Claude 7c3f101fe0 Add asterisk, nextcloud, onlyoffice, mattermost services + vendor/easy-asterisk
asterisk.sh (homelab):
- Easy Asterisk PBX with self-hosted coturn TURN server
- Vendored from outis1one/easy-asterisk v0.10.0 for offline install
- LAN-only or FQDN mode (TLS + TURN relay for remote access)
- Auto-answer SIP headers for intercom use case
- Authelia SSO for web admin; WEB_ADMIN_AUTH_DISABLED=true when chosen
- UFW rules: 5060-5061, 8080, 8088-8089, 3478, 10000-20000/udp, 49152-49252/udp
- Builds custom Docker image from vendor/easy-asterisk/

nextcloud.sh (utilities):
- Custom Dockerfile: nextcloud:apache + smbclient (SMB external storage)
- MariaDB 10.11 sidecar with matching env vars
- OVERWRITEPROTOCOL/OVERWRITECLIURL/TRUSTED_PROXIES set for Caddy
- Enables files_external app after first-run init (waits up to 90s)

onlyoffice.sh (utilities):
- JWT generated once, preserved across re-runs
- _ensure_yq: auto-installs yq v4 for FileBrowser config patching
- _wire_nextcloud: idempotent occ wiring (DocumentServerUrl, jwt_secret)
- _wire_filebrowser: patches config.yaml + restarts container
- Caddy block overrides X-Frame-Options to allow iframe embedding

mattermost.sh (utilities):
- PostgreSQL 15-alpine + Mattermost Team Edition + coturn (port 3479)
- 8443/udp for Calls plugin RTC server
- coturn uses --use-auth-secret HMAC mode (required by Calls plugin)
- SITE_URL computed from SITE_DOMAIN, promptable
- UFW: 8443/udp, 3479, 49153-49352/udp

vendor/easy-asterisk/:
- All upstream source files vendored for offline/self-contained installs
- Dockerfile, docker/entrypoint.sh, docker/coturn-entrypoint.sh
- easy-asterisk-v0.10.0.sh (6929-line management script)
- scripts/vpn-diagnostics.sh, scripts/dns-whitelist.sh
- .env.example

https://claude.ai/code/session_014CCYqVwW6d6f5dw1qRokYt
2026-06-09 00:28:38 +00:00
Claude ab778868df Fix Mattermost Calls, add Authelia to Asterisk web admin
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
2026-06-08 18:41:46 +00:00
Claude dc1552f5d3 Fix asterisk.sh: symlink→cp, management script mount, TURN_SERVER, ports
- 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
2026-06-08 18:41:46 +00:00
Claude 0d81839c80 Vendor easy-asterisk source files; fix asterisk.sh and onlyoffice.sh
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
2026-06-08 18:41:46 +00:00
Claude 9f667705ae Add Easy Asterisk PBX service with self-hosted coturn TURN server
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
2026-06-08 18:41:17 +00:00