From 638150450d69e19010119ee76ffcaf14ad3748d0 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 29 Oct 2026 00:00:29 +0100 Subject: [PATCH 1/3] deploy: Skript zum Einrichten des Portals auf 131 Env-Datei, Unit, nginx-Block 8450, nft-Regel, Audience portal, CORS am Core und Neubau von Portal und Login in einem idempotenten Lauf mit Sicherungen. Co-Authored-By: Claude Sonnet 5.5 --- deploy/131-portal-einrichten.sh | 184 ++++++++++++++++++++++++++++++++ docs/BETRIEB-PORTAL.md | 3 +- 2 files changed, 186 insertions(+), 1 deletion(-) create mode 100755 deploy/131-portal-einrichten.sh diff --git a/deploy/131-portal-einrichten.sh b/deploy/131-portal-einrichten.sh new file mode 100755 index 00000000..96af7838 --- /dev/null +++ b/deploy/131-portal-einrichten.sh @@ -0,0 +1,184 @@ +#!/usr/bin/env bash +# Richtet das Portal auf 131 ein (Dienst, nginx 8450, Firewall, CORS am Core, +# Audience "portal", Neubau von Portal und Login). Als root auf 131 ausfuehren: +# scp deploy/131-portal-einrichten.sh root@192.168.1.131:/root/ && ssh root@192.168.1.131 'bash /root/131-portal-einrichten.sh' +# Idempotent; geaenderte Dateien werden vorher nach $BAK gesichert. Geheimnisse +# werden nur zwischen Dateien kopiert und nie ausgegeben. +set -euo pipefail + +HOST=192.168.1.131 +INSTALL=/opt/nexarch-web/portal +ACCOUNT=/opt/nexarch-web/account +SRC=/root/nexarch-code +BAK=/root/portal-einrichten-$(date +%Y%m%d-%H%M%S) +NGINX_SITE=/etc/nginx/sites-available/nexarch-gui +mkdir -p "$BAK" + +say() { printf '\n== %s\n' "$*"; } +fail() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; } + +[ "$(id -u)" = 0 ] || fail "als root ausfuehren" +[ -f "$NGINX_SITE" ] || fail "$NGINX_SITE fehlt" +[ -f /etc/nftables.conf ] || fail "/etc/nftables.conf fehlt" +[ -f /etc/nexarch/policy-api.env ] || fail "/etc/nexarch/policy-api.env fehlt" +[ -d "$INSTALL/web/portal/.next" ] || fail "Portal-Build unter $INSTALL fehlt" +grep -qE 'include\s+/etc/nginx/conf\.d/\*\.conf' /etc/nginx/nginx.conf || fail "nginx.conf bindet conf.d nicht ein" +nginx -t &1 | tail -1 + +say "1/8 Quellstand" +git -C "$SRC" fetch -q origin /dev/null || sed -i -E 's/^(NEXARCH_ACCOUNT_MODULE_AUDIENCES=.*)$/\1,portal/' "$ENVF" +else + echo 'NEXARCH_ACCOUNT_MODULE_AUDIENCES=dms,portal' >> "$ENVF" +fi +grep '^NEXARCH_ACCOUNT_MODULE_AUDIENCES=' "$ENVF" +echo "Hinweis: mit mehr als einer Audience lehnt der Core Anfragen ohne ?module= ab. Auf 131 nutzt bisher kein Frontend eine Sitzung (geprueft), das Portal setzt module=portal." + +say "4/8 nginx: CORS am Core (8443) und Block 8450" +cp -p "$NGINX_SITE" "$BAK/nexarch-gui" +cat > /etc/nginx/conf.d/nexarch-cors-map.conf <<'MAP' +map $http_origin $nexarch_cors_origin { + default ""; + "~^https://192\.168\.1\.131:(8444|8445|8446|8447|8448|8449|8450)$" $http_origin; +} +MAP +cat > /etc/nginx/snippets-nexarch-cors.conf <<'SNIP' +if ($request_method = OPTIONS) { + add_header Access-Control-Allow-Origin $nexarch_cors_origin always; + add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; + add_header Access-Control-Allow-Headers "Content-Type" always; + add_header Access-Control-Allow-Credentials "true" always; + add_header Content-Length 0; + return 204; +} +add_header Access-Control-Allow-Origin $nexarch_cors_origin always; +add_header Access-Control-Allow-Credentials "true" always; +SNIP +python3 - "$NGINX_SITE" <<'PY' +import re, sys +p = sys.argv[1] +s = open(p).read() +inc = " include /etc/nginx/snippets-nexarch-cors.conf;\n" +for loc in ("/auth/", "/account/"): + pat = " location %s {\n" % loc + first = s.index(pat) # erster Treffer = Block auf 8443 + after = first + len(pat) + if inc not in s[after:after + len(inc) + 1]: + s = s[:after] + inc + s[after:] +if "listen 8450 ssl;" not in s: + s = s.rstrip("\n") + """ + +# NEXARCH Web - Portal +server { + listen 8450 ssl; + http2 on; + server_name _; + ssl_certificate /etc/ssl/archivmail/archivmail.crt; + ssl_certificate_key /etc/ssl/archivmail/archivmail.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + location / { + proxy_pass http://127.0.0.1:3057; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} +""" +open(p, "w").write(s) +PY +if nginx -t &1; then + echo "nginx -t ok (Reload folgt nach der Firewall)" +else + cp -p "$BAK/nexarch-gui" "$NGINX_SITE"; rm -f /etc/nginx/conf.d/nexarch-cors-map.conf /etc/nginx/snippets-nexarch-cors.conf + fail "nginx -t fehlgeschlagen, Aenderung zurueckgenommen" +fi + +say "5/8 Firewall: Port 8450" +cp -p /etc/nftables.conf "$BAK/nftables.conf" +grep -q '8449, 8450' /etc/nftables.conf || sed -i 's/8448, 8449 }/8448, 8449, 8450 }/' /etc/nftables.conf +grep -q '8450' /etc/nftables.conf || fail "8450 konnte nicht in nftables.conf eingetragen werden" +nft -c -f /etc/nftables.conf /etc/systemd/system/nexarch-web-portal.service +systemctl daemon-reload + local base=$1 app=$2; shift 2 + local dir="$base/web/$app" + [ -d "$dir" ] || fail "$dir fehlt" + tar czf "$BAK/$app-next.tgz" -C "$dir" .next + rsync -a --delete --exclude node_modules --exclude .next "$SRC/web/shl/" "$base/web/shl/" + rsync -a --delete --exclude node_modules --exclude .next "$SRC/web/$app/" "$dir/" + chown -R nexarch:nexarch "$base/web/shl" "$dir" + if [ -d "$dir/node_modules/@nexarch/shl" ] && [ ! -L "$dir/node_modules/@nexarch/shl" ]; then + rm -rf "$dir/node_modules/@nexarch/shl"; ln -s ../../../shl "$dir/node_modules/@nexarch/shl" + fi + mkdir -p "$base/.home"; chown nexarch:nexarch "$base/.home" + if runuser -u nexarch -- env HOME="$base/.home" NPM_CONFIG_CACHE="$base/.home/.npm" "$@" bash -c "cd '$dir' && { [ -d node_modules ] || npm ci --no-audit --no-fund; } && npx next build --webpack" "$BAK/$app-build.log" 2>&1; then + echo "Build $app ok" + else + tail -5 "$BAK/$app-build.log" + rm -rf "$dir/.next"; tar xzf "$BAK/$app-next.tgz" -C "$dir" + fail "Build $app fehlgeschlagen, alter Stand zurueckgestellt (Log: $BAK/$app-build.log)" + fi +} + +say "7/8 Neubau Portal und Login aus origin/main" +build_app "$INSTALL" portal NEXT_PUBLIC_CORE_API_BASE=https://$HOST:8443 NEXT_PUBLIC_LOGIN_URL=https://$HOST:8443/ NEXT_PUBLIC_TOKEN_MODULE=portal +if [ -d "$ACCOUNT/web/account" ]; then + build_app "$ACCOUNT" account NEXT_PUBLIC_PORTAL_URL=https://$HOST:8450/ + systemctl restart nexarch-web-account ` und nimmt nginx- und nft-Änderungen bei Prüffehlern zurück. +- CORS: Der Core (8443) liefert auf 131 selbst keine CORS-Header; Frontends auf anderen Ports (8444–8450) brauchen sie für `/auth/module-token`. Das Skript trägt sie in nginx ein (`/etc/nginx/conf.d/nexarch-cors-map.conf`, Ursprünge `https://192.168.1.131:8444–8450`). - Voraussetzung für Anmeldung: `nexarch-account-api` läuft (Passwort der DB-Rolle muss zur DSN in `account-api.env` passen; bei Authentifizierungsfehler beendet sich der Dienst mit Exit 2 und startet nicht neu). ## 204 (Dev/Test, Demo `nexarch-portal-live`) -- 2.47.3 From 154f3fc5051aa314fb86452134b992a822da651d Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 29 Oct 2026 10:55:30 +0100 Subject: [PATCH 2/3] deploy: shl bekommt node_modules-Link, sonst findet der Portal-Build react nicht Auf 131 hat /opt/nexarch-web/portal/web/shl kein node_modules; der rsync laesst node_modules aus. Typpruefung scheiterte mit TS2307 'react'. Co-Authored-By: Claude Sonnet 5.5 --- deploy/131-portal-einrichten.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/131-portal-einrichten.sh b/deploy/131-portal-einrichten.sh index 96af7838..67544f7c 100755 --- a/deploy/131-portal-einrichten.sh +++ b/deploy/131-portal-einrichten.sh @@ -145,6 +145,7 @@ build_app() { # build_app if [ -d "$dir/node_modules/@nexarch/shl" ] && [ ! -L "$dir/node_modules/@nexarch/shl" ]; then rm -rf "$dir/node_modules/@nexarch/shl"; ln -s ../../../shl "$dir/node_modules/@nexarch/shl" fi + [ -e "$base/web/shl/node_modules" ] || ln -s "../$app/node_modules" "$base/web/shl/node_modules" mkdir -p "$base/.home"; chown nexarch:nexarch "$base/.home" if runuser -u nexarch -- env HOME="$base/.home" NPM_CONFIG_CACHE="$base/.home/.npm" "$@" bash -c "cd '$dir' && { [ -d node_modules ] || npm ci --no-audit --no-fund; } && npx next build --webpack" "$BAK/$app-build.log" 2>&1; then echo "Build $app ok" -- 2.47.3 From d7172a1699e9256d975618f81e6b09d12a5d3bb7 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 29 Oct 2026 10:58:13 +0100 Subject: [PATCH 3/3] deploy: npm ci bei abweichender Lockdatei, shl nutzt node_modules der App Account auf 131 hat Next 14.2.35, die Quelle braucht 16.3.5 (--webpack unbekannt). Abhaengigkeiten werden jetzt per Lockdatei-Hash erneuert, shl/node_modules wird auf die der App verlinkt (eine React-Instanz). Co-Authored-By: Claude Sonnet 5.5 --- deploy/131-portal-einrichten.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/deploy/131-portal-einrichten.sh b/deploy/131-portal-einrichten.sh index 67544f7c..c7281fcc 100755 --- a/deploy/131-portal-einrichten.sh +++ b/deploy/131-portal-einrichten.sh @@ -142,12 +142,20 @@ build_app() { # build_app rsync -a --delete --exclude node_modules --exclude .next "$SRC/web/shl/" "$base/web/shl/" rsync -a --delete --exclude node_modules --exclude .next "$SRC/web/$app/" "$dir/" chown -R nexarch:nexarch "$base/web/shl" "$dir" + mkdir -p "$base/.home"; chown nexarch:nexarch "$base/.home" + local lock; lock=$(sha256sum "$dir/package-lock.json" | cut -d' ' -f1) + if [ ! -d "$dir/node_modules" ] || [ "$(cat "$dir/node_modules/.nexarch-lock" 2>/dev/null)" != "$lock" ]; then + runuser -u nexarch -- env HOME="$base/.home" NPM_CONFIG_CACHE="$base/.home/.npm" bash -c "cd '$dir' && npm ci --no-audit --no-fund && echo $lock > node_modules/.nexarch-lock" "$BAK/$app-npm.log" 2>&1 \ + || { tail -5 "$BAK/$app-npm.log"; fail "npm ci $app fehlgeschlagen (Log: $BAK/$app-npm.log)"; } + fi if [ -d "$dir/node_modules/@nexarch/shl" ] && [ ! -L "$dir/node_modules/@nexarch/shl" ]; then rm -rf "$dir/node_modules/@nexarch/shl"; ln -s ../../../shl "$dir/node_modules/@nexarch/shl" fi + if [ -e "$base/web/shl/node_modules" ] && [ ! -L "$base/web/shl/node_modules" ]; then + mv "$base/web/shl/node_modules" "$BAK/$app-shl-node_modules" + fi [ -e "$base/web/shl/node_modules" ] || ln -s "../$app/node_modules" "$base/web/shl/node_modules" - mkdir -p "$base/.home"; chown nexarch:nexarch "$base/.home" - if runuser -u nexarch -- env HOME="$base/.home" NPM_CONFIG_CACHE="$base/.home/.npm" "$@" bash -c "cd '$dir' && { [ -d node_modules ] || npm ci --no-audit --no-fund; } && npx next build --webpack" "$BAK/$app-build.log" 2>&1; then + if runuser -u nexarch -- env HOME="$base/.home" NPM_CONFIG_CACHE="$base/.home/.npm" "$@" bash -c "cd '$dir' && npx next build --webpack" "$BAK/$app-build.log" 2>&1; then echo "Build $app ok" else tail -5 "$BAK/$app-build.log" -- 2.47.3