release 2026.07.07-24520d4
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env bash
|
||||
# EasyMCP / SapB1Mcp — Setup auf dem Docker-Host (Pull-Deployment).
|
||||
#
|
||||
# Die einzige Datei, die ein Kunde braucht. Bezug:
|
||||
# curl -fsSLO https://git.kraemerweb.de/kraemerweb/easymcp-release/raw/branch/main/setup.sh
|
||||
#
|
||||
# Aufruf:
|
||||
# bash setup.sh # neueste Version (latest)
|
||||
# bash setup.sh <version> # bestimmte Version (Tag im Release-Repo)
|
||||
#
|
||||
# Was das Skript tut:
|
||||
# 1. Holt die Deployment-Dateien (docker-compose.yml, hydra.yml, .env.example)
|
||||
# anonym aus dem öffentlichen Release-Repo — passend zur gewählten Version.
|
||||
# 2. Erzeugt secrets/creds_key (32 Byte base64, Verschlüsselung der SAP-Credentials).
|
||||
# 3. Legt .env aus .env.example an und generiert PG_PASSWORD + SECRETS_SYSTEM;
|
||||
# setzt APP_VERSION (= gewählte Version bzw. latest) und PROJECT_DIR.
|
||||
# 4. Pullt das Updater-Image (für die Update-Funktion des Admin-UI).
|
||||
#
|
||||
# Idempotent: eine vorhandene .env und ein vorhandener creds_key werden NIE
|
||||
# überschrieben — nur APP_VERSION und PROJECT_DIR werden nachgezogen. Die
|
||||
# Deployment-Dateien werden immer auf den Stand der gewählten Version gebracht.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
RELEASE_BASE="${RELEASE_BASE:-https://git.kraemerweb.de/kraemerweb/easymcp-release}"
|
||||
REGISTRY_IMAGE_BASE="${REGISTRY_IMAGE_BASE:-git.kraemerweb.de/kraemerweb}"
|
||||
|
||||
VERSION="${1:-}"
|
||||
if [ -n "$VERSION" ]; then
|
||||
REF="tag/${VERSION}"
|
||||
APP_VERSION="$VERSION"
|
||||
else
|
||||
REF="branch/main"
|
||||
APP_VERSION="latest"
|
||||
fi
|
||||
|
||||
info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
|
||||
ok() { printf '\033[1;32m ✓\033[0m %s\n' "$*"; }
|
||||
warn() { printf '\033[1;33m !\033[0m %s\n' "$*"; }
|
||||
fail() { printf '\033[1;31mFEHLER:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
# --- Zufallswerte (openssl bevorzugt, /dev/urandom als Fallback) -------------
|
||||
rand_hex() { # $1 = Byte-Anzahl; Ausgabe hex (URL-sicher, auch für DSN-URLs)
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
openssl rand -hex "$1" | tr -d ' \r\n'
|
||||
else
|
||||
od -An -N"$1" -tx1 /dev/urandom | tr -d ' \r\n'
|
||||
fi
|
||||
}
|
||||
rand_b64() { # $1 = Byte-Anzahl; Ausgabe base64 (eine Zeile)
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
openssl rand -base64 "$1" | tr -d '\r\n'
|
||||
else
|
||||
head -c "$1" /dev/urandom | base64 | tr -d '\r\n'
|
||||
fi
|
||||
}
|
||||
set_env() { # $1 = Name, $2 = Wert — setzt bzw. ergänzt NAME=WERT in .env
|
||||
if grep -q "^$1=" .env; then
|
||||
sed -i "s|^$1=.*|$1=$2|" .env
|
||||
else
|
||||
printf '%s=%s\n' "$1" "$2" >> .env
|
||||
fi
|
||||
}
|
||||
fetch() { # $1 = Datei im Release-Repo, $2 = Zielname — atomar ersetzen
|
||||
curl -fsSL "$RELEASE_BASE/raw/$REF/$1" -o "$2.new" \
|
||||
|| fail "Download fehlgeschlagen: $RELEASE_BASE/raw/$REF/$1 (Version/Netzwerk prüfen)"
|
||||
mv "$2.new" "$2"
|
||||
}
|
||||
|
||||
# --- Vorbedingungen -----------------------------------------------------------
|
||||
command -v curl >/dev/null 2>&1 || fail "curl nicht gefunden — bitte installieren."
|
||||
command -v docker >/dev/null 2>&1 || fail "docker nicht gefunden — bitte Docker Engine installieren."
|
||||
docker info >/dev/null 2>&1 || fail "Docker-Daemon nicht erreichbar (läuft der Dienst? Rechte? Ggf. sudo verwenden)."
|
||||
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
COMPOSE="docker compose"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
COMPOSE="docker-compose"
|
||||
else
|
||||
fail "Weder 'docker compose' (Plugin v2) noch 'docker-compose' gefunden."
|
||||
fi
|
||||
|
||||
# --- 1. Deployment-Dateien holen -----------------------------------------------
|
||||
info "Hole Deployment-Dateien (${VERSION:-latest}) aus $RELEASE_BASE ..."
|
||||
fetch docker-compose.yml docker-compose.yml
|
||||
fetch hydra.yml hydra.yml
|
||||
fetch .env.example .env.example
|
||||
ok "docker-compose.yml, hydra.yml, .env.example aktualisiert."
|
||||
|
||||
# --- 2. creds_key --------------------------------------------------------------
|
||||
info "Prüfe secrets/creds_key ..."
|
||||
mkdir -p secrets
|
||||
if [ -f secrets/creds_key ]; then
|
||||
ok "secrets/creds_key existiert bereits — bleibt unverändert."
|
||||
else
|
||||
( umask 077; rand_b64 32 > secrets/creds_key )
|
||||
ok "secrets/creds_key erzeugt (chmod 600)."
|
||||
echo " WICHTIG: Diese Datei SICHERN. Ohne sie sind die gespeicherten SAP-Zugangsdaten unlesbar."
|
||||
fi
|
||||
|
||||
# --- 3. .env -------------------------------------------------------------------
|
||||
info "Prüfe .env ..."
|
||||
if [ -f .env ]; then
|
||||
ok ".env existiert bereits — Secrets/Werte bleiben unverändert."
|
||||
current="$(sed -n 's/^APP_VERSION=//p' .env | head -n1)"
|
||||
set_env APP_VERSION "$APP_VERSION"
|
||||
if [ -n "$current" ] && [ "$current" != "$APP_VERSION" ]; then
|
||||
ok "Update: APP_VERSION ${current} -> ${APP_VERSION} (wirkt nach '${COMPOSE} pull' + '${COMPOSE} up -d')."
|
||||
fi
|
||||
else
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
PG_PASSWORD="$(rand_hex 24)" # nur [0-9a-f]: sicher für Hydras DSN-URL
|
||||
SECRETS_SYSTEM="$(rand_hex 32)" # Hydra-Systemschlüssel — nach Inbetriebnahme NIE mehr ändern
|
||||
set_env PG_PASSWORD "$PG_PASSWORD"
|
||||
set_env SECRETS_SYSTEM "$SECRETS_SYSTEM"
|
||||
set_env APP_VERSION "$APP_VERSION"
|
||||
ok ".env angelegt, PG_PASSWORD + SECRETS_SYSTEM generiert (chmod 600)."
|
||||
fi
|
||||
# Host-Pfad des Deployments — braucht die Update-Funktion des Admin-UI (der
|
||||
# Einweg-Updater mountet das Projektverzeichnis pfad-identisch). Bei jedem Lauf
|
||||
# aktualisieren, falls das Verzeichnis umgezogen ist.
|
||||
set_env PROJECT_DIR "$(pwd)"
|
||||
|
||||
# --- 4. Updater-Image für die Admin-UI-Update-Funktion --------------------------
|
||||
info "Pulle Updater-Image ..."
|
||||
if docker pull "$REGISTRY_IMAGE_BASE/sapb1mcp-updater:latest" >/dev/null; then
|
||||
ok "Updater-Image bereit."
|
||||
else
|
||||
warn "Updater-Image konnte nicht gepullt werden — Registry-Zugriff prüfen; das Admin-UI-Update funktioniert sonst nicht."
|
||||
fi
|
||||
|
||||
# --- 5. Nächste Schritte ---------------------------------------------------------
|
||||
cat <<EOF
|
||||
|
||||
============================================================================
|
||||
Setup abgeschlossen. Bitte jetzt in der .env die Umgebungswerte anpassen:
|
||||
|
||||
PUBLIC_ISSUER öffentliche HTTPS-URL des OAuth-Issuers (Reverse Proxy -> Port 4444)
|
||||
LOGIN_URL öffentliche HTTPS-URL des Login-Dienstes (Reverse Proxy -> Port 8081)
|
||||
MCP_RESOURCE_URL öffentliche HTTPS-URL des MCP-Servers (Reverse Proxy -> Port 8080)
|
||||
SL_BASE_URL SAP Service Layer, z. B. https://sap-host:50000/b1s/ (trailing /b1s/ ist Pflicht)
|
||||
SL_COMPANYDB SAP-Firmendatenbank
|
||||
ADMIN_SAP_USER SAP-Benutzer, der das Admin-UI öffnen darf
|
||||
MCP_ALLOWED_USERS kommagetrennte SAP-Benutzer mit MCP-Dauerzugriff
|
||||
|
||||
Optional: SL_INSECURE (self-signed SAP-Zertifikat), BIND_ADDR/ADMIN_BIND und
|
||||
*_HOST_PORT, falls der Reverse Proxy auf einem anderen Host läuft.
|
||||
|
||||
Danach den Stack starten:
|
||||
|
||||
${COMPOSE} pull
|
||||
${COMPOSE} up -d
|
||||
|
||||
Status prüfen: ${COMPOSE} ps (alle Dauerläufer müssen "healthy" werden)
|
||||
Updates später: im Admin-UI unter „Update" — oder erneut 'bash setup.sh [version]'
|
||||
gefolgt von '${COMPOSE} pull' + '${COMPOSE} up -d'. Details: INSTALL.md
|
||||
============================================================================
|
||||
EOF
|
||||
Reference in New Issue
Block a user