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 property="og:title" content="Jörg Lohrer – Blog" />
|
||||
<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)" />
|
||||
<link rel="canonical" href="__SITE_URL__/" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
<title>Jörg Lohrer</title>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
# Deploy: SvelteKit-Build nach svelte.joerg-lohrer.de per FTPS.
|
||||
# Credentials kommen aus ./.env.local (gitignored), Variablen-Prefix SVELTE_FTP_.
|
||||
# Deploy: SvelteKit-Build per FTPS nach einem der All-Inkl-Webroots.
|
||||
# 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
|
||||
|
||||
|
|
@ -12,44 +21,99 @@ if [ ! -f .env.local ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# nur SVELTE_FTP_* exportieren (via Tempfile — process substitution ist nicht
|
||||
# überall verfügbar, je nach Shell/Sandbox).
|
||||
_ENV_TMP="$(mktemp)"
|
||||
trap 'rm -f "$_ENV_TMP"' EXIT
|
||||
grep -E '^SVELTE_FTP_' .env.local > "$_ENV_TMP" || true
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
. "$_ENV_TMP"
|
||||
set +a
|
||||
TARGET="${DEPLOY_TARGET:-svelte}"
|
||||
case "$TARGET" in
|
||||
svelte)
|
||||
PREFIX="SVELTE_FTP_"
|
||||
PUBLIC_URL="https://svelte.joerg-lohrer.de/"
|
||||
SITE_URL="https://svelte.joerg-lohrer.de"
|
||||
;;
|
||||
staging)
|
||||
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
|
||||
if [ -z "${!v:-}" ]; then
|
||||
echo "FEHLER: $v fehlt in .env.local." >&2
|
||||
# Werte direkt aus .env.local lesen (nicht via `source`, weil
|
||||
# password-shell-metazeichen wie ( ) & kein sourcing überstehen).
|
||||
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
|
||||
fi
|
||||
done
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
||||
find "$BUILD_DIR" -type f -print0 | while IFS= read -r -d '' local_file; do
|
||||
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"
|
||||
# --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.
|
||||
curl -sSf --ssl-reqd --tls-max 1.2 --ftp-create-dirs \
|
||||
--retry 3 --retry-delay 2 --retry-all-errors \
|
||||
--connect-timeout 15 \
|
||||
--user "$SVELTE_FTP_USER:$SVELTE_FTP_PASS" \
|
||||
--user "$FTP_USER:$FTP_PASS" \
|
||||
-T "$local_file" "$remote"
|
||||
done
|
||||
|
||||
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