scripts/deploy-prod: Ziel aus git-ignorierter scripts/deploy.env (Fallback)

Ohne Ziel-Argument liest das Skript DEPLOY_TARGET aus scripts/deploy.env
(git-ignoriert; Vorlage scripts/deploy.env.example ist eingecheckt). Argument
hat weiterhin Vorrang.

Der Wert wird bewusst NICHT via `source` gelesen, weil bash bei `host:~/pfad`
die Tilde nach dem ':' lokal expandieren wuerde; stattdessen roh ausgelesen,
Whitespace/CR + umgebende Quotes gestrippt, das ~ bleibt fuer die Remote-Seite
erhalten. Lokal verifiziert: Fallback greift, ~ bleibt in unquoted/single-/
double-quoted erhalten (kein lokales $HOME), Quotes entfernt.

.gitignore: scripts/deploy.env ergaenzt (die vorhandene .env-Regel greift wegen
des abweichenden Dateinamens nicht). README (de/en) aktualisiert; Beispielpfad
auf die htdocs-ssl-Direktaufschaltung umgestellt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-07-22 07:05:40 +02:00
co-authored by Claude Opus 4.8
parent ecf767cfb5
commit 6b83af7d73
5 changed files with 67 additions and 23 deletions
+2
View File
@@ -60,6 +60,8 @@ frontend/dist/
.env
.env.local
*.local
# Deploy-Ziel (scripts/deploy-prod.sh) — lokal halten; Vorlage .example bleibt drin
scripts/deploy.env
# === Temporäres ===
tmp/
+12 -6
View File
@@ -89,18 +89,24 @@ Workflow ersetzt ihn sonst aus `VERSION` + Commit-Zahl).
**Bequemer: `scripts/deploy-prod.sh`.** Das Skript macht genau den obigen
Prod-Build **und** die beiden Nacharbeiten (LICENSE danebenlegen + Link
geradeziehen, Footer-Version + Commit-Link wie beim Pages-Workflow) und spiegelt
das Ergebnis per rsync/SSH auf einen Server. Zielpfad als einziges Pflichtargument:
das Ergebnis per rsync/SSH auf einen Server:
```bash
scripts/deploy-prod.sh mih00@mih00.hostsharing.net:~/doms/javagil.de/subs-ssl/werkbaum/
scripts/deploy-prod.sh mih00@mih00.hostsharing.net:~/doms/werkbaum.javagil.de/htdocs-ssl
```
Das Ziel ist entweder dieses Argument oder — ohne Argument — die Variable
`DEPLOY_TARGET` aus der **git-ignorierten** Datei `scripts/deploy.env` (Vorlage:
`scripts/deploy.env.example`, einmal kopieren und den Pfad eintragen). Ein
Argument hat Vorrang.
Ohne `-y` zeigt es zuerst eine `--dry-run`-Vorschau und fragt nach. `rsync
--delete` sorgt dafür, dass am Ziel **nichts Altes** stehen bleibt — das
Zielverzeichnis gilt also als exklusiv für Werkbaum. (Hostsharing: für eine
**Subdomain** wie `werkbank.javagil.de` unter der aufgeschalteten Domain
`javagil.de` ist das Web-Verzeichnis `…/subs-ssl/<name>/`; eine direkt
aufgeschaltete Domain läge unter `…/htdocs-ssl/`.)
Zielverzeichnis gilt also als exklusiv für Werkbaum (eine laufende Let's-Encrypt-
Challenge unter `.well-known/` wird per `--filter=protect` ausgenommen, web-
taugliche Rechte 755/644 werden erzwungen). (Hostsharing: eine **direkt
aufgeschaltete** Domain liefert aus `…/htdocs-ssl/`; als **Subdomain** unter einer
anderen Domain läge das Web-Verzeichnis in `…/subs-ssl/<name>/`.)
## Projektdokumente
+12 -6
View File
@@ -87,18 +87,24 @@ from `VERSION` + commit count).
**Easier: `scripts/deploy-prod.sh`.** The script runs exactly that prod build
**and** both fix-ups (drop `LICENSE` alongside + straighten the link, footer
version + commit link just like the Pages workflow) and mirrors the result to a
server via rsync/SSH. The target path is the only required argument:
server via rsync/SSH:
```bash
scripts/deploy-prod.sh mih00@mih00.hostsharing.net:~/doms/javagil.de/subs-ssl/werkbaum/
scripts/deploy-prod.sh mih00@mih00.hostsharing.net:~/doms/werkbaum.javagil.de/htdocs-ssl
```
The target is either this argument or — with no argument — the `DEPLOY_TARGET`
variable from the **git-ignored** file `scripts/deploy.env` (template:
`scripts/deploy.env.example`, copy it once and fill in the path). An argument
takes precedence.
Without `-y` it first shows a `--dry-run` preview and asks for confirmation.
`rsync --delete` ensures **nothing old** is left at the target — so the target
directory is treated as exclusive to Werkbaum. (Hostsharing: for a **subdomain**
like `werkbank.javagil.de` under the parent domain `javagil.de` the web directory
is `…/subs-ssl/<name>/`; a directly-served domain would live under
`…/htdocs-ssl/`.)
directory is treated as exclusive to Werkbaum (an in-flight Let's Encrypt
challenge under `.well-known/` is spared via `--filter=protect`, and web-friendly
755/644 permissions are enforced). (Hostsharing: a **directly-served** domain is
served from `…/htdocs-ssl/`; as a **subdomain** under another domain the web
directory would be `…/subs-ssl/<name>/`.)
## Project documents
+30 -11
View File
@@ -9,15 +9,19 @@
# nichts Altes stehen.
#
# Verwendung:
# scripts/deploy-prod.sh [-y] <rsync-ziel>
# scripts/deploy-prod.sh [-y] [rsync-ziel]
#
# -y ohne Rückfrage spiegeln (sonst erst Vorschau via --dry-run + Nachfrage)
#
# Beispiel (Hostsharing, Subdomain werkbank.javagil.de unter der Domain
# javagil.de — deshalb `subs-ssl/`; wäre die Domain direkt aufgeschaltet, läge
# das Web-Verzeichnis in `htdocs-ssl/`):
# Das Ziel ist entweder das Argument ODER — wenn keins angegeben ist — die
# Variable DEPLOY_TARGET aus der git-ignorierten Datei scripts/deploy.env
# (Vorlage: scripts/deploy.env.example). Ein Argument hat Vorrang.
#
# scripts/deploy-prod.sh mih00@mih00.hostsharing.net:~/doms/javagil.de/subs-ssl/werkbaum/
# Beispiel (Hostsharing, direkt aufgeschaltete Domain werkbaum.javagil.de —
# Web-Verzeichnis in `htdocs-ssl/`; als Subdomain unter einer anderen Domain
# läge es stattdessen in `subs-ssl/<name>/`):
#
# scripts/deploy-prod.sh mih00@mih00.hostsharing.net:~/doms/werkbaum.javagil.de/htdocs-ssl
#
# ACHTUNG: Das Zielverzeichnis wird als exklusiv für Werkbaum angenommen —
# `--delete` entfernt dort ALLES, was nicht zum Bundle gehört.
@@ -43,16 +47,31 @@ for arg in "$@"; do
esac
done
if [ -z "$TARGET" ]; then
echo "Usage: $0 [-y] <rsync-ziel>" >&2
echo " z.B. $0 mih00@mih00.hostsharing.net:~/doms/javagil.de/subs-ssl/werkbaum/" >&2
exit 2
fi
# ---- Repo-Wurzel (Skript ist unter scripts/) ----
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
# ---- Ziel: Argument hat Vorrang, sonst scripts/deploy.env (git-ignoriert) ----
ENV_FILE="$ROOT/scripts/deploy.env"
if [ -z "$TARGET" ] && [ -f "$ENV_FILE" ]; then
# Bewusst NICHT via `source` lesen: bash würde bei `host:~/pfad` das ~ nach dem
# ':' LOKAL expandieren. Stattdessen roh auslesen (letzte Definition gewinnt),
# trailing Whitespace/CR und umgebende Quotes strippen — das ~ bleibt so für
# die Remote-Seite erhalten.
TARGET="$(sed -n -E 's/^[[:space:]]*DEPLOY_TARGET[[:space:]]*=[[:space:]]*//p' "$ENV_FILE" \
| tail -1 | sed -E 's/[[:space:]]+$//')"
TARGET="${TARGET#\"}"; TARGET="${TARGET%\"}"
TARGET="${TARGET#\'}"; TARGET="${TARGET%\'}"
[ -n "$TARGET" ] && echo "==> Ziel aus scripts/deploy.env: ${TARGET}"
fi
if [ -z "$TARGET" ]; then
echo "Usage: $0 [-y] <rsync-ziel>" >&2
echo " oder DEPLOY_TARGET in scripts/deploy.env setzen (Vorlage: scripts/deploy.env.example)" >&2
echo " z.B. $0 mih00@mih00.hostsharing.net:~/doms/werkbaum.javagil.de/htdocs-ssl" >&2
exit 2
fi
# ---- 1) Prod-Build (ohne Build-Hinweis) ----
if [ ! -d frontend/node_modules ]; then
echo "==> node_modules fehlt — npm ci"
+11
View File
@@ -0,0 +1,11 @@
# Vorlage für scripts/deploy.env — kopieren und anpassen:
# cp scripts/deploy.env.example scripts/deploy.env
#
# scripts/deploy.env ist git-ignoriert (enthält deinen Server/Pfad) und wird von
# scripts/deploy-prod.sh benutzt, wenn KEIN Ziel als Argument übergeben wird.
# Ein Argument hat immer Vorrang.
#
# Wert = rsync-Ziel (user@host:pfad). Das `~` wird auf der Remote-Seite
# aufgelöst; Anführungszeichen sind optional. Keine Kommentare hinter dem Wert.
DEPLOY_TARGET=mih00@mih00.hostsharing.net:~/doms/werkbaum.javagil.de/htdocs-ssl