From b26cdd55dc96c265928a1ba5271f83cd4bee088e Mon Sep 17 00:00:00 2001 From: MickLesk <47820557+MickLesk@users.noreply.github.com> Date: Fri, 23 Oct 2026 10:52:44 +0200 Subject: [PATCH] Storyteller: build the runtime like upstream's Dockerfile Only the Next.js app was built before. The standalone server now also gets the worker and file-write-worker bundles, the native align prebuilds, the icu-segmentation wasm, @parcel/watcher and kuromoji, plus the env vars that point at them, and whisper.cpp with the tiny.en model is installed through ghost-story's CLI. Packages and the readium version follow upstream (#16628). Update still used the pre-monorepo paths, and CLEAN_INSTALL wiped /opt/storyteller including the data directory; it now keeps data/, rebuilds the same way and rewrites the unit, so existing installs move over. --- ct/storyteller.sh | 78 +++++++++++++++++++++++--------- install/storyteller-install.sh | 82 +++++++++++++++++++++------------- 2 files changed, 107 insertions(+), 53 deletions(-) diff --git a/ct/storyteller.sh b/ct/storyteller.sh index d3b28a5ee..dd6a01e94 100644 --- a/ct/storyteller.sh +++ b/ct/storyteller.sh @@ -31,42 +31,78 @@ function update_script() { exit fi - NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs + NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs if check_for_gl_release "storyteller" "storyteller-platform/storyteller" "" "" "web-v2"; then msg_info "Stopping Service" systemctl stop storyteller msg_ok "Stopped Service" + msg_info "Installing Dependencies" + $STD apt install -y cmake argon2 libcurl4t64 libxml2 + msg_ok "Installed Dependencies" + + fetch_and_deploy_gh_release "readium" "readium/cli" "prebuild" "v0.9.1" "/opt/readium" "readium_linux_$(arch_resolve "x86_64" "arm64").tar.gz" + create_backup /opt/storyteller/.env - - CLEAN_INSTALL=1 fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2" - + CLEAN_INSTALL=1 CLEAN_INSTALL_KEEP="data" fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2" restore_backup - msg_info "Rebuilding Storyteller" + msg_info "Building Storyteller (Patience)" cd /opt/storyteller - export NODE_OPTIONS="--max-old-space-size=4096" - - $STD corepack yarn install --network-timeout 600000 - $STD gcc -g -fPIC -rdynamic -shared web/sqlite/uuid.c -o web/sqlite/uuid.c.so - export CI=1 + $STD corepack yarn install export NODE_ENV=production export NEXT_TELEMETRY_DISABLED=1 export SQLITE_NATIVE_BINDING=/opt/storyteller/node_modules/better-sqlite3/build/Release/better_sqlite3.node $STD corepack yarn workspaces foreach -Rpt --from @storyteller-platform/web --exclude @storyteller-platform/eslint run build - mkdir -p /opt/storyteller/web/.next/standalone/web/.next/static - cp -rT /opt/storyteller/web/.next/static /opt/storyteller/web/.next/standalone/web/.next/static - if [[ -d /opt/storyteller/web/public ]]; then - mkdir -p /opt/storyteller/web/.next/standalone/web/public - cp -rT /opt/storyteller/web/public /opt/storyteller/web/.next/standalone/web/public + STANDALONE=/opt/storyteller/applications/web/.next/standalone + WEB_DIR="$STANDALONE/applications/web" + mkdir -p "$WEB_DIR"/{public,.next/static,.next/cache,migrations,sqlite,scripts} + cp -rT applications/web/public "$WEB_DIR/public" + cp -rT applications/web/.next/static "$WEB_DIR/.next/static" + cp -rT applications/web/migrations "$WEB_DIR/migrations" + cp applications/web/sqlite/uuid.c.so "$WEB_DIR/sqlite/" + cp docker-scripts/reset-password.sh "$WEB_DIR/scripts/" + cp -r applications/web/work-dist applications/web/file-write-dist "$WEB_DIR/" + mkdir -p "$WEB_DIR/work-dist/@storyteller-platform/align/prebuilds" + cp -r "libraries/align/prebuilds/linux-$(arch_resolve "x64" "arm64")" "$WEB_DIR/work-dist/@storyteller-platform/align/prebuilds/" + cp node_modules/@echogarden/icu-segmentation-wasm/wasm/*.wasm "$WEB_DIR/work-dist/" + cp -rT node_modules/@parcel "$STANDALONE/node_modules/@parcel" + cp -rT node_modules/kuromoji "$STANDALONE/node_modules/kuromoji" + ln -sf /opt/storyteller/.env "$WEB_DIR/.env" + msg_ok "Built Storyteller" + + msg_info "Updating Whisper" + WHISPER_VARIANT="linux-$(arch_resolve "x64" "arm64")-cpu" + $STD node /opt/storyteller/libraries/ghost-story/dist/cli/bin.js install binary "$WHISPER_VARIANT" + $STD node /opt/storyteller/libraries/ghost-story/dist/cli/bin.js install model tiny.en + if [[ "$WHISPER_VARIANT" == "linux-x64-cpu" ]]; then + $STD node /opt/storyteller/libraries/ghost-story/dist/cli/bin.js install binary linux-x64-cpu-legacy fi - mkdir -p /opt/storyteller/web/.next/standalone/web/migrations - cp -rT /opt/storyteller/web/migrations /opt/storyteller/web/.next/standalone/web/migrations - mkdir -p /opt/storyteller/web/.next/standalone/web/sqlite - cp -rT /opt/storyteller/web/sqlite /opt/storyteller/web/.next/standalone/web/sqlite - ln -sf /opt/storyteller/.env /opt/storyteller/web/.next/standalone/web/.env - msg_ok "Rebuilt Storyteller" + msg_ok "Updated Whisper" + + cat </etc/systemd/system/storyteller.service +[Unit] +Description=Storyteller +After=network.target + +[Service] +Type=simple +User=root +WorkingDirectory=${WEB_DIR} +EnvironmentFile=/opt/storyteller/.env +Environment=SQLITE_NATIVE_BINDING=${STANDALONE}/node_modules/better-sqlite3/build/Release/better_sqlite3.node +Environment=ERROR_ALIGN_NATIVE_BINDING=${WEB_DIR}/work-dist/@storyteller-platform/align/ +Environment=STORYTELLER_WORKER=worker.mjs +Environment=STORYTELLER_FILE_WRITE_WORKER=fileWriteWorker.mjs +ExecStart=/usr/bin/node --enable-source-maps server.js +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload msg_info "Starting Service" systemctl start storyteller diff --git a/install/storyteller-install.sh b/install/storyteller-install.sh index b852e9d8c..bb136dea2 100644 --- a/install/storyteller-install.sh +++ b/install/storyteller-install.sh @@ -17,24 +17,57 @@ msg_info "Installing Dependencies" $STD apt install -y \ build-essential \ git \ - pkg-config \ - libsqlite3-dev \ + cmake \ + python3 \ sqlite3 \ - python3-setuptools \ - ffmpeg + libsqlite3-dev \ + argon2 \ + ffmpeg \ + libcurl4t64 \ + libxml2 msg_ok "Installed Dependencies" -NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs +NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs -fetch_and_deploy_gh_release "readium" "readium/cli" "prebuild" "latest" "/opt/readium" "readium_linux_$(arch_resolve "x86_64" "arm64").tar.gz" +fetch_and_deploy_gh_release "readium" "readium/cli" "prebuild" "v0.9.1" "/opt/readium" "readium_linux_$(arch_resolve "x86_64" "arm64").tar.gz" ln -sf /opt/readium/readium /usr/local/bin/readium fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2" -msg_info "Setting up Storyteller" +msg_info "Building Storyteller (Patience)" cd /opt/storyteller +$STD corepack yarn install +export NODE_ENV=production +export NEXT_TELEMETRY_DISABLED=1 +export SQLITE_NATIVE_BINDING=/opt/storyteller/node_modules/better-sqlite3/build/Release/better_sqlite3.node +$STD corepack yarn workspaces foreach -Rpt --from @storyteller-platform/web --exclude @storyteller-platform/eslint run build +# Assembled like upstream's Dockerfile: Next does not trace the workers, native prebuilds and wasm files +STANDALONE=/opt/storyteller/applications/web/.next/standalone +WEB_DIR="$STANDALONE/applications/web" +mkdir -p "$WEB_DIR"/{public,.next/static,.next/cache,migrations,sqlite,scripts} +cp -rT applications/web/public "$WEB_DIR/public" +cp -rT applications/web/.next/static "$WEB_DIR/.next/static" +cp -rT applications/web/migrations "$WEB_DIR/migrations" +cp applications/web/sqlite/uuid.c.so "$WEB_DIR/sqlite/" +cp docker-scripts/reset-password.sh "$WEB_DIR/scripts/" +cp -r applications/web/work-dist applications/web/file-write-dist "$WEB_DIR/" +mkdir -p "$WEB_DIR/work-dist/@storyteller-platform/align/prebuilds" +cp -r "libraries/align/prebuilds/linux-$(arch_resolve "x64" "arm64")" "$WEB_DIR/work-dist/@storyteller-platform/align/prebuilds/" +cp node_modules/@echogarden/icu-segmentation-wasm/wasm/*.wasm "$WEB_DIR/work-dist/" +cp -rT node_modules/@parcel "$STANDALONE/node_modules/@parcel" +cp -rT node_modules/kuromoji "$STANDALONE/node_modules/kuromoji" +msg_ok "Built Storyteller" -$STD corepack yarn install --network-timeout 600000 -$STD gcc -g -fPIC -rdynamic -shared applications/web/sqlite/uuid.c -o applications/web/sqlite/uuid.c.so +msg_info "Installing Whisper" +WHISPER_VARIANT="linux-$(arch_resolve "x64" "arm64")-cpu" +$STD node /opt/storyteller/libraries/ghost-story/dist/cli/bin.js install binary "$WHISPER_VARIANT" +$STD node /opt/storyteller/libraries/ghost-story/dist/cli/bin.js install model tiny.en +if [[ "$WHISPER_VARIANT" == "linux-x64-cpu" ]]; then + $STD node /opt/storyteller/libraries/ghost-story/dist/cli/bin.js install binary linux-x64-cpu-legacy +fi +msg_ok "Installed Whisper" + +msg_info "Configuring Storyteller" +mkdir -p /opt/storyteller/data STORYTELLER_SECRET_KEY=$(openssl rand -base64 32) cat </opt/storyteller/.env STORYTELLER_SECRET_KEY=${STORYTELLER_SECRET_KEY} @@ -45,33 +78,14 @@ READIUM_PORT=9000 NODE_ENV=production NEXT_TELEMETRY_DISABLED=1 EOF -mkdir -p /opt/storyteller/data +chmod 600 /opt/storyteller/.env +ln -sf /opt/storyteller/.env "$WEB_DIR/.env" cat <~/storyteller.creds Storyteller Credentials ======================= Secret Key: ${STORYTELLER_SECRET_KEY} EOF -msg_ok "Set up Storyteller" - -msg_info "Building Storyteller" -cd /opt/storyteller -export CI=1 -export NODE_ENV=production -export NEXT_TELEMETRY_DISABLED=1 -export SQLITE_NATIVE_BINDING=/opt/storyteller/node_modules/better-sqlite3/build/Release/better_sqlite3.node -$STD corepack yarn workspaces foreach -Rpt --from @storyteller-platform/web --exclude @storyteller-platform/eslint run build -mkdir -p /opt/storyteller/applications/web/.next/standalone/applications/web/.next/static -cp -rT /opt/storyteller/applications/web/.next/static /opt/storyteller/applications/web/.next/standalone/applications/web/.next/static -if [[ -d /opt/storyteller/applications/web/public ]]; then - mkdir -p /opt/storyteller/applications/web/.next/standalone/applications/web/public - cp -rT /opt/storyteller/applications/web/public /opt/storyteller/applications/web/.next/standalone/applications/web/public -fi -mkdir -p /opt/storyteller/applications/web/.next/standalone/applications/web/migrations -cp -rT /opt/storyteller/applications/web/migrations /opt/storyteller/applications/web/.next/standalone/applications/web/migrations -mkdir -p /opt/storyteller/applications/web/.next/standalone/applications/web/sqlite -cp -rT /opt/storyteller/applications/web/sqlite /opt/storyteller/applications/web/.next/standalone/applications/web/sqlite -ln -sf /opt/storyteller/.env /opt/storyteller/applications/web/.next/standalone/applications/web/.env -msg_ok "Built Storyteller" +msg_ok "Configured Storyteller" msg_info "Creating Service" cat </etc/systemd/system/storyteller.service @@ -82,8 +96,12 @@ After=network.target [Service] Type=simple User=root -WorkingDirectory=/opt/storyteller/applications/web/.next/standalone/applications/web +WorkingDirectory=${WEB_DIR} EnvironmentFile=/opt/storyteller/.env +Environment=SQLITE_NATIVE_BINDING=${STANDALONE}/node_modules/better-sqlite3/build/Release/better_sqlite3.node +Environment=ERROR_ALIGN_NATIVE_BINDING=${WEB_DIR}/work-dist/@storyteller-platform/align/ +Environment=STORYTELLER_WORKER=worker.mjs +Environment=STORYTELLER_FILE_WRITE_WORKER=fileWriteWorker.mjs ExecStart=/usr/bin/node --enable-source-maps server.js Restart=on-failure RestartSec=5