fix(updates): route frontend deploy through host-side updater
When DashCaddy is installed without `${DASHBOARD_DIR}:/app/dashboard` bind
mounted into the container (e.g. legacy DNS2 setup where Caddy serves from
/var/www/dashcaddy-status/), the self-updater's in-container copy to
/app/dashboard was a silent no-op — leaving the dashboard stale across
self-updates, which led to CSP-hash mismatches and a broken UI.
- self-updater: new hostFrontendDir option (default `/var/www/dashcaddy-status`
on Linux, overridable via DASHCADDY_HOST_FRONTEND_DIR). When set, defer the
frontend copy to the host-side updater by passing frontendStagingDir +
frontendTargetDir in trigger.json. Now also includes `js/` in the copy list.
- dashcaddy-update.sh: read those new trigger fields and sync the dashboard
files on the host. Auto-detect fallback for older self-updaters (no fields
in trigger.json) so a single release upgrade self-heals.
This commit is contained in:
@@ -87,12 +87,18 @@ main() {
|
||||
|
||||
# Parse trigger.json (uses python3 which is available on all supported distros)
|
||||
local action version from_version staging_dir api_source_dir commit
|
||||
local frontend_staging_dir frontend_target_dir
|
||||
action=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}'))['action'])")
|
||||
version=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}'))['version'])")
|
||||
from_version=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}'))['fromVersion'])")
|
||||
staging_dir=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}'))['stagingDir'])")
|
||||
api_source_dir=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}'))['apiSourceDir'])")
|
||||
commit=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}')).get('commit') or '')")
|
||||
# Frontend paths — optional (older self-updaters don't write these). When
|
||||
# present, this script also syncs the dashboard files (Caddy serves them
|
||||
# directly from the host; the container path /app/dashboard isn't mounted).
|
||||
frontend_staging_dir=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}')).get('frontendStagingDir') or '')")
|
||||
frontend_target_dir=$(python3 -c "import json; print(json.load(open('${TRIGGER_FILE}')).get('frontendTargetDir') or '')")
|
||||
|
||||
log "=== ${action^^}: v${from_version} -> v${version} ==="
|
||||
log "Staging: ${staging_dir}"
|
||||
@@ -147,6 +153,39 @@ main() {
|
||||
echo "$commit" > "$api_source_dir/VERSION"
|
||||
fi
|
||||
|
||||
# 4b. Sync frontend. Caddy serves the dashboard directly from the host
|
||||
# filesystem; the container-side copy in older self-updater.js builds wrote
|
||||
# to /app/dashboard which isn't always mounted, so the real sync happens
|
||||
# here. Trigger fields take precedence; if absent (older self-updater),
|
||||
# fall back to: staging dir's sibling status/ + first existing known target.
|
||||
if [[ -z "$frontend_staging_dir" ]]; then
|
||||
parent_staging=$(dirname "$staging_dir")
|
||||
[[ -d "$parent_staging/status" ]] && frontend_staging_dir="$parent_staging/status"
|
||||
fi
|
||||
if [[ -z "$frontend_target_dir" ]]; then
|
||||
for candidate in /var/www/dashcaddy-status /etc/dashcaddy/sites/status; do
|
||||
[[ -d "$candidate" ]] && frontend_target_dir="$candidate" && break
|
||||
done
|
||||
fi
|
||||
if [[ -n "$frontend_staging_dir" && -n "$frontend_target_dir" && -d "$frontend_staging_dir" ]]; then
|
||||
log "Syncing frontend: $frontend_staging_dir -> $frontend_target_dir"
|
||||
mkdir -p "$frontend_target_dir"
|
||||
[[ -f "$frontend_staging_dir/index.html" ]] && cp -f "$frontend_staging_dir/index.html" "$frontend_target_dir/index.html"
|
||||
[[ -f "$frontend_staging_dir/sw.js" ]] && cp -f "$frontend_staging_dir/sw.js" "$frontend_target_dir/sw.js"
|
||||
for sub in dist css vendor js; do
|
||||
if [[ -d "$frontend_staging_dir/$sub" ]]; then
|
||||
mkdir -p "$frontend_target_dir/$sub"
|
||||
cp -rf "$frontend_staging_dir/$sub"/* "$frontend_target_dir/$sub/" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
# assets/ is mounted into the container; usually already in sync via bind
|
||||
# mount, but if a release ships new assets we want them on disk too.
|
||||
if [[ -d "$frontend_staging_dir/assets" ]]; then
|
||||
mkdir -p "$frontend_target_dir/assets"
|
||||
cp -rf "$frontend_staging_dir/assets"/* "$frontend_target_dir/assets/" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# 5. Rebuild container
|
||||
log "Rebuilding container..."
|
||||
cd "$api_source_dir"
|
||||
|
||||
Reference in New Issue
Block a user