From 946e5fadb03c26a6d12b4c5ba96de42f165ef3d9 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 7 Jan 2026 18:06:09 +0100 Subject: [PATCH] Refactor deployment script to handle symlinking of public data conditionally based on git tracking status, improving error handling for uncommitted changes. Update PM2 configuration to directly start the Node server for Nuxt 4 production builds in both harheimertc.config.cjs and harheimertc.simple.cjs. Modify user ID handling in registration options to use Uint8Array for compatibility with @simplewebauthn/server. --- deploy-production.sh | 34 ++++++++++++++----- harheimertc.config.cjs | 5 +-- harheimertc.simple.cjs | 4 +-- .../passkeys/registration-options.post.js | 3 +- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/deploy-production.sh b/deploy-production.sh index 6a91c36..bea563f 100755 --- a/deploy-production.sh +++ b/deploy-production.sh @@ -48,9 +48,24 @@ ensure_symlink_dir() { echo " Linked $src -> $target" } +has_tracked_files_under() { + local prefix="$1" # e.g. public/data + # If any file is tracked under this path, symlinking the directory will break git operations + git ls-files "$prefix" | head -n 1 | grep -q . +} + echo "0. Ensuring persistent data directories (recommended)..." ensure_symlink_dir "server/data" "$DATA_ROOT/server-data" -ensure_symlink_dir "public/data" "$DATA_ROOT/public-data" + +# IMPORTANT: Only symlink public/data if it's not tracked by git. +# Otherwise git will error with "path is beyond a symbolic link". +if has_tracked_files_under "public/data"; then + echo " Skipping symlink for public/data (tracked files detected in git)." + echo " Recommendation: remove public/data/*.csv from git history and keep them only as production data." +else + ensure_symlink_dir "public/data" "$DATA_ROOT/public-data" +fi + ensure_symlink_dir "public/uploads" "$DATA_ROOT/public-uploads" echo "" @@ -89,9 +104,13 @@ if [ -n "$(git status --porcelain | grep '^UU\|^AA\|^DD')" ]; then git reset --hard HEAD fi -# Stash any local changes (including production data) -echo " Stashing local changes..." -git stash push -m "Production deployment stash $(date)" || true +# Ensure a clean working tree (we avoid git stash because it breaks with symlinked data paths) +if [ -n "$(git status --porcelain)" ]; then + echo "ERROR: Working tree is not clean. Please commit/revert changes before deployment." + echo "Hint: If this is caused by tracked production data files, remove them from git tracking." + git status --porcelain + exit 1 +fi # Pull latest changes echo " Pulling latest changes..." @@ -144,12 +163,9 @@ if [ ! -s server/data/users.json ]; then exit 1 fi -# 7. Cleanup stash (Backups werden bewusst behalten) +# 7. Cleanup (Backups werden bewusst behalten) echo "" -echo "7. Cleaning up stash (keeping backups in $BACKUP_ROOT)..." -# Clear the deployment stash (keep other stashes) -echo " Clearing deployment stash..." -git stash list | grep "Production deployment stash" | head -1 | cut -d: -f1 | xargs -r git stash drop +echo "7. Keeping backups in $BACKUP_ROOT (no git stash used)." # 8. Restart PM2 echo "" diff --git a/harheimertc.config.cjs b/harheimertc.config.cjs index 8785ae1..71b7b99 100644 --- a/harheimertc.config.cjs +++ b/harheimertc.config.cjs @@ -9,8 +9,9 @@ try { module.exports = { apps: [{ name: 'harheimertc', - script: 'npm', - args: 'run start', + // Nuxt 4 production build: direkt den Node-Server starten (kein "preview mode") + script: 'node', + args: '.output/server/index.mjs', cwd: '/var/www/harheimertc', instances: 1, autorestart: true, diff --git a/harheimertc.simple.cjs b/harheimertc.simple.cjs index c0f3c90..c21175c 100644 --- a/harheimertc.simple.cjs +++ b/harheimertc.simple.cjs @@ -9,8 +9,8 @@ try { module.exports = { apps: [{ name: 'harheimertc', - script: 'npm', - args: 'run start', + script: 'node', + args: '.output/server/index.mjs', instances: 1, autorestart: true, watch: false, diff --git a/server/api/auth/passkeys/registration-options.post.js b/server/api/auth/passkeys/registration-options.post.js index 208674c..88bf970 100644 --- a/server/api/auth/passkeys/registration-options.post.js +++ b/server/api/auth/passkeys/registration-options.post.js @@ -31,7 +31,8 @@ export default defineEventHandler(async (event) => { const options = await generateRegistrationOptions({ rpName, rpID: rpId, - userID: String(user.id), + // @simplewebauthn/server erwartet inzwischen Uint8Array/Buffer statt String + userID: new TextEncoder().encode(String(user.id)), userName: user.email, // Keine Attestation-Daten speichern attestationType: 'none',