From 353fa0f3f3d205740682770d726d50ef8cec6c6b Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Sat, 9 May 2026 17:21:05 -0400 Subject: [PATCH] seed-data.sh: always refresh static/ and index.html from image The React bundle hash changes every time the UI is rebuilt. With the old no-clobber approach, a redeployed container kept serving the old bundle because the static/ directory already existed on the data volume. Fix: always overwrite index.html, asset-manifest.json, and the entire static/ subdirectory from /core/static on every container start. These are build artifacts (not operator-edited content) so overwriting is safe. All other top-level entries (channels/, config/, etc.) remain no-clobber. --- deploy/truenas/core/seed-data.sh | 36 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/deploy/truenas/core/seed-data.sh b/deploy/truenas/core/seed-data.sh index 6b883fa..f249ac2 100755 --- a/deploy/truenas/core/seed-data.sh +++ b/deploy/truenas/core/seed-data.sh @@ -1,10 +1,16 @@ #!/bin/sh -# seed-data.sh — first-boot seed of /core/data with Dragon Fork -# landing page artifacts (index.html, whep-player.html). +# seed-data.sh — boot-time seed of /core/data with Dragon Fork +# landing page artifacts (index.html, whep-player.html, compiled UI bundle). # -# Runs from the entrypoint before bin/core. Skips itself if any of the -# target files already exist, so user-supplied content (or content from -# a previous deploy that they edited) is never clobbered. +# Runs from the entrypoint before bin/core. +# +# Strategy: +# - Build artifacts (index.html, asset-manifest.json, static/) are ALWAYS +# overwritten so a redeployed container picks up the new UI bundle even +# when the data volume already exists. The React bundle hash changes every +# build, so leaving the old bundle in place would serve a stale UI. +# - Everything else (channels/, _player/, _playersite/, custom HTML files) +# is no-clobber so operator-edited content is never lost. # # Source dir: /core/static (baked by the Dockerfile) # Target dir: /core/data (operator-mounted; what Core serves at /) @@ -23,13 +29,25 @@ if [ ! -d "$DST" ]; then mkdir -p "$DST" fi -# Iterate over both files and directories. The Restreamer UI bundle -# ships subdirectories (_player, _playersite, static) so this needs -# the recursive flag; the no-clobber check on the top-level name keeps -# operator-edited content safe. +# Always-overwrite entries: build artifacts whose content changes every deploy. +for always in index.html asset-manifest.json static; do + src="$SRC/$always" + dst="$DST/$always" + [ -e "$src" ] || continue + if [ -d "$src" ]; then + cp -Rfp "$src" "$dst" + else + cp -fp "$src" "$dst" + fi + echo "seed-data: refreshed $always -> $dst" +done + +# No-clobber entries: everything else (operator content, player bundles, etc.) for f in "$SRC"/* "$SRC"/.[!.]*; do [ -e "$f" ] || continue name=$(basename "$f") + # Skip entries already handled above. + case "$name" in index.html|asset-manifest.json|static) continue ;; esac if [ ! -e "$DST/$name" ]; then cp -Rp "$f" "$DST/$name" echo "seed-data: copied $name -> $DST/$name"