spa/deploy: dynamische site-url via __SITE_URL__-platzhalter, staging + prod als deploy-targets
app.html nutzt __SITE_URL__ als platzhalter in og:url und canonical. deploy-svelte.sh ersetzt ihn nach dem build pro ziel via sed: - svelte → https://svelte.joerg-lohrer.de (default, bisheriger SVELTE_FTP_-pfad) - staging → https://staging.joerg-lohrer.de (STAGING_FTP_-pfad, webroot joerglohrer26) - prod → https://joerg-lohrer.de (STAGING_FTP_-pfad, cutover-ziel) env-auslese aus .env.local nicht mehr via `source` (bricht bei sonderzeichen im passwort), sondern via awk pro schlüssel. build wird jetzt vom deploy-skript angestoßen, damit immer gegen den frischen html-stand gebaut wird. app/.env.example dokumentiert PUBLIC_SITE_URL (derzeit ungenutzt, da der platzhalter-ansatz zuverlässiger ist als runtime-env für prerender). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
75ad8b87fa
commit
34c62cb944
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Öffentliche Site-URL für Canonical-Link und og:url-Meta-Tags.
|
||||||
|
# Zur Build-Zeit fest; gilt domain-übergreifend (svelte./staging./haupt-
|
||||||
|
# domain). Für jeden Deploy-Zweck kann eine andere URL gesetzt werden.
|
||||||
|
#
|
||||||
|
# Beispiele:
|
||||||
|
# PUBLIC_SITE_URL=https://svelte.joerg-lohrer.de
|
||||||
|
# PUBLIC_SITE_URL=https://staging.joerg-lohrer.de
|
||||||
|
# PUBLIC_SITE_URL=https://joerg-lohrer.de
|
||||||
|
PUBLIC_SITE_URL=https://joerg-lohrer.de
|
||||||
|
|
@ -6,8 +6,9 @@
|
||||||
<meta name="description" content="Jörg Lohrer – Blog (Nostr-basiert)" />
|
<meta name="description" content="Jörg Lohrer – Blog (Nostr-basiert)" />
|
||||||
<meta property="og:title" content="Jörg Lohrer – Blog" />
|
<meta property="og:title" content="Jörg Lohrer – Blog" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content="https://svelte.joerg-lohrer.de/" />
|
<meta property="og:url" content="__SITE_URL__/" />
|
||||||
<meta property="og:description" content="Jörg Lohrer – Blog (Nostr-basiert)" />
|
<meta property="og:description" content="Jörg Lohrer – Blog (Nostr-basiert)" />
|
||||||
|
<link rel="canonical" href="__SITE_URL__/" />
|
||||||
<meta name="robots" content="index, follow" />
|
<meta name="robots" content="index, follow" />
|
||||||
<title>Jörg Lohrer</title>
|
<title>Jörg Lohrer</title>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Deploy: SvelteKit-Build nach svelte.joerg-lohrer.de per FTPS.
|
# Deploy: SvelteKit-Build per FTPS nach einem der All-Inkl-Webroots.
|
||||||
# Credentials kommen aus ./.env.local (gitignored), Variablen-Prefix SVELTE_FTP_.
|
# Credentials kommen aus ./.env.local (gitignored), Variablen-Prefix je Ziel.
|
||||||
|
#
|
||||||
|
# Zielauswahl via DEPLOY_TARGET-Env-Variable:
|
||||||
|
# - DEPLOY_TARGET=svelte (default) → svelte.joerg-lohrer.de via SVELTE_FTP_*
|
||||||
|
# - DEPLOY_TARGET=staging → staging.joerg-lohrer.de via STAGING_FTP_*
|
||||||
|
#
|
||||||
|
# Beispiele:
|
||||||
|
# ./scripts/deploy-svelte.sh # default: svelte
|
||||||
|
# DEPLOY_TARGET=staging ./scripts/deploy-svelte.sh # staging-probelauf
|
||||||
|
# DEPLOY_TARGET=svelte ./scripts/deploy-svelte.sh # explizit
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
@ -12,44 +21,99 @@ if [ ! -f .env.local ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# nur SVELTE_FTP_* exportieren (via Tempfile — process substitution ist nicht
|
TARGET="${DEPLOY_TARGET:-svelte}"
|
||||||
# überall verfügbar, je nach Shell/Sandbox).
|
case "$TARGET" in
|
||||||
_ENV_TMP="$(mktemp)"
|
svelte)
|
||||||
trap 'rm -f "$_ENV_TMP"' EXIT
|
PREFIX="SVELTE_FTP_"
|
||||||
grep -E '^SVELTE_FTP_' .env.local > "$_ENV_TMP" || true
|
PUBLIC_URL="https://svelte.joerg-lohrer.de/"
|
||||||
set -a
|
SITE_URL="https://svelte.joerg-lohrer.de"
|
||||||
# shellcheck disable=SC1090
|
;;
|
||||||
. "$_ENV_TMP"
|
staging)
|
||||||
set +a
|
PREFIX="STAGING_FTP_"
|
||||||
|
PUBLIC_URL="https://staging.joerg-lohrer.de/"
|
||||||
|
SITE_URL="https://staging.joerg-lohrer.de"
|
||||||
|
;;
|
||||||
|
prod)
|
||||||
|
# Deploy auf staging-ftp (joerglohrer26 = aktueller cutover-webroot),
|
||||||
|
# aber mit og:url auf der hauptdomain.
|
||||||
|
PREFIX="STAGING_FTP_"
|
||||||
|
PUBLIC_URL="https://joerg-lohrer.de/"
|
||||||
|
SITE_URL="https://joerg-lohrer.de"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "FEHLER: unbekanntes DEPLOY_TARGET='$TARGET' (erlaubt: svelte, staging, prod)." >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
for v in SVELTE_FTP_HOST SVELTE_FTP_USER SVELTE_FTP_PASS SVELTE_FTP_REMOTE_PATH; do
|
# Werte direkt aus .env.local lesen (nicht via `source`, weil
|
||||||
if [ -z "${!v:-}" ]; then
|
# password-shell-metazeichen wie ( ) & kein sourcing überstehen).
|
||||||
echo "FEHLER: $v fehlt in .env.local." >&2
|
read_env() {
|
||||||
|
local key="$1"
|
||||||
|
# nimmt die erste zeile, die exakt mit KEY= beginnt, schneidet alles nach
|
||||||
|
# dem ersten = ab, gibt den rest 1:1 zurück (auch mit sonderzeichen).
|
||||||
|
awk -F= -v k="$key" 'BEGIN{found=0} $1==k && !found { sub("^" k "=",""); print; found=1 }' .env.local
|
||||||
|
}
|
||||||
|
|
||||||
|
FTP_HOST_KEY="${PREFIX}HOST"
|
||||||
|
FTP_USER_KEY="${PREFIX}USER"
|
||||||
|
FTP_PASS_KEY="${PREFIX}PASS"
|
||||||
|
FTP_PATH_KEY="${PREFIX}REMOTE_PATH"
|
||||||
|
|
||||||
|
FTP_HOST="$(read_env "$FTP_HOST_KEY")"
|
||||||
|
FTP_USER="$(read_env "$FTP_USER_KEY")"
|
||||||
|
FTP_PASS="$(read_env "$FTP_PASS_KEY")"
|
||||||
|
FTP_REMOTE_PATH="$(read_env "$FTP_PATH_KEY")"
|
||||||
|
|
||||||
|
for pair in "$FTP_HOST_KEY:$FTP_HOST" "$FTP_USER_KEY:$FTP_USER" \
|
||||||
|
"$FTP_PASS_KEY:$FTP_PASS" "$FTP_PATH_KEY:$FTP_REMOTE_PATH"; do
|
||||||
|
key="${pair%%:*}"
|
||||||
|
val="${pair#*:}"
|
||||||
|
if [ -z "$val" ]; then
|
||||||
|
echo "FEHLER: $key fehlt in .env.local." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
BUILD_DIR="$ROOT/app/build"
|
BUILD_DIR="$ROOT/app/build"
|
||||||
|
|
||||||
|
echo "Baue SvelteKit …"
|
||||||
|
(cd "$ROOT/app" && npm run build >/dev/null 2>&1) || {
|
||||||
|
echo "FEHLER: Build fehlgeschlagen. 'cd app && npm run build' manuell ausführen zum Debuggen." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
if [ ! -d "$BUILD_DIR" ]; then
|
if [ ! -d "$BUILD_DIR" ]; then
|
||||||
echo "FEHLER: app/build nicht vorhanden. Bitte vorher 'npm run build' in app/ ausführen." >&2
|
echo "FEHLER: app/build nicht vorhanden nach build." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Lade Build von $BUILD_DIR nach ftp://$SVELTE_FTP_HOST$SVELTE_FTP_REMOTE_PATH"
|
# __SITE_URL__-Platzhalter in allen HTML-Dateien durch die ziel-spezifische
|
||||||
|
# SITE_URL ersetzen (für og:url / canonical). Nicht im quellcode hart
|
||||||
|
# setzen, damit ein builder einmal baut und mehrere domains damit bedienen
|
||||||
|
# kann.
|
||||||
|
echo "Patche __SITE_URL__ → $SITE_URL in HTML-Dateien …"
|
||||||
|
find "$BUILD_DIR" -type f -name "*.html" -print0 | while IFS= read -r -d '' html_file; do
|
||||||
|
# sed -i '' für macOS-kompatibilität (bsd sed braucht leeres backup-arg)
|
||||||
|
sed -i '' "s|__SITE_URL__|$SITE_URL|g" "$html_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Ziel: $TARGET ($PUBLIC_URL)"
|
||||||
|
echo "Lade Build von $BUILD_DIR nach ftp://$FTP_HOST$FTP_REMOTE_PATH"
|
||||||
|
|
||||||
# pro Datei ein curl-Upload (zuverlässig auf macOS ohne lftp)
|
# pro Datei ein curl-Upload (zuverlässig auf macOS ohne lftp)
|
||||||
find "$BUILD_DIR" -type f -print0 | while IFS= read -r -d '' local_file; do
|
find "$BUILD_DIR" -type f -print0 | while IFS= read -r -d '' local_file; do
|
||||||
rel="${local_file#$BUILD_DIR/}"
|
rel="${local_file#$BUILD_DIR/}"
|
||||||
remote="ftp://$SVELTE_FTP_HOST${SVELTE_FTP_REMOTE_PATH%/}/$rel"
|
remote="ftp://$FTP_HOST${FTP_REMOTE_PATH%/}/$rel"
|
||||||
echo " → $rel"
|
echo " → $rel"
|
||||||
# --tls-max 1.2: All-Inkl/Kasserver FTPS schließt bei TLS 1.3 die Data-
|
# --tls-max 1.2: All-Inkl/Kasserver FTPS schließt bei TLS 1.3 die Data-
|
||||||
# Connection mit "426 Transfer aborted" — mit 1.2 läuft es sauber durch.
|
# Connection mit "426 Transfer aborted" — mit 1.2 läuft es sauber durch.
|
||||||
curl -sSf --ssl-reqd --tls-max 1.2 --ftp-create-dirs \
|
curl -sSf --ssl-reqd --tls-max 1.2 --ftp-create-dirs \
|
||||||
--retry 3 --retry-delay 2 --retry-all-errors \
|
--retry 3 --retry-delay 2 --retry-all-errors \
|
||||||
--connect-timeout 15 \
|
--connect-timeout 15 \
|
||||||
--user "$SVELTE_FTP_USER:$SVELTE_FTP_PASS" \
|
--user "$FTP_USER:$FTP_PASS" \
|
||||||
-T "$local_file" "$remote"
|
-T "$local_file" "$remote"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Upload fertig. Live-Check:"
|
echo "Upload fertig. Live-Check:"
|
||||||
curl -sIL "https://svelte.joerg-lohrer.de/" | head -5
|
curl -sIL "$PUBLIC_URL" | head -5
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue