deploy: installer + systemd-units, Core auf 192.168.1.131 in Betrieb
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s

deploy/install.sh: idempotenter Installer fuer Debian/systemd. Legt
Systembenutzer 'nexarch', Postgres-Rolle+Registry-DB an, baut alle 7
Core-Binaries (cmd/core + *-devserver), wendet Registry-Migrationen an
(nur bei leerer DB), generiert Secrets (Audit-Admin-Token, Ed25519-
Lizenzschluesselpaar) nach /etc/nexarch/core.env (0600), installiert und
startet je Dienst einen systemd-Service.

Tatsaechlich auf 192.168.1.131 ausgefuehrt und verifiziert: alle 7 Dienste
laufen (systemctl active), alle Health-Endpunkte antworten 200. Zweiter
Installer-Lauf bestaetigt Idempotenz (ueberspringt bestehende Rolle/DB/
Secrets/Migrationen, Dienste bleiben durchgehend aktiv).

Hinweis: kein unified Server (siehe QA-05/AUD-06-Befund) - weiterhin 7
getrennte Binaries/Ports, dieser Installer deployt sie so wie sie sind.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
This commit is contained in:
sysops
2026-08-29 19:03:20 +02:00
co-authored by Claude Sonnet 5
parent 4de9310213
commit 278d26f7bd
9 changed files with 291 additions and 0 deletions
+150
View File
@@ -0,0 +1,150 @@
#!/usr/bin/env bash
# NEXARCH Core Installer/Deployer fuer eine Debian/systemd-Zielumgebung.
#
# Baut alle Core-Binaries (cmd/core + die *-devserver), legt Postgres-Rolle
# und Registry-Datenbank an (falls nicht vorhanden), wendet die
# Registry-Migrationen an, generiert Secrets (falls nicht vorhanden) und
# installiert+startet jeden Dienst als eigenen systemd-Service.
#
# Idempotent: mehrfacher Aufruf ist sicher — vorhandene Rolle/DB/Secrets
# werden nicht ueberschrieben, Migrationen nur angewendet, wenn die
# Registry-DB noch leer ist (siehe Abschnitt "Migrationen" unten).
#
# Aufruf (als root): ./deploy/install.sh
#
# Ueberschreibbar per Umgebungsvariable:
# NEXARCH_INSTALL_DIR (Default: /opt/nexarch-core)
# NEXARCH_PG_ROLE (Default: nexarch_core)
# NEXARCH_PG_REGISTRY_DB (Default: nexarch_registry)
# NEXARCH_BRANCH (Default: aktueller Branch dieses Checkouts)
set -euo pipefail
INSTALL_DIR="${NEXARCH_INSTALL_DIR:-/opt/nexarch-core}"
PG_ROLE="${NEXARCH_PG_ROLE:-nexarch_core}"
PG_DB="${NEXARCH_PG_REGISTRY_DB:-nexarch_registry}"
ENV_FILE=/etc/nexarch/core.env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
if [ "$(id -u)" -ne 0 ]; then
echo "Bitte als root ausfuehren (legt Systembenutzer, systemd-Units und Postgres-Rolle an)." >&2
exit 1
fi
echo "== 1. Systembenutzer =="
if ! id nexarch >/dev/null 2>&1; then
useradd --system --no-create-home --shell /usr/sbin/nologin nexarch
echo "Benutzer 'nexarch' angelegt."
else
echo "Benutzer 'nexarch' existiert bereits."
fi
echo "== 2. Postgres-Rolle und Registry-Datenbank =="
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname = '${PG_ROLE}'" | grep -q 1; then
PG_PASSWORD="$(openssl rand -hex 24)"
sudo -u postgres psql -v ON_ERROR_STOP=1 -c "CREATE ROLE ${PG_ROLE} WITH LOGIN PASSWORD '${PG_PASSWORD}';"
echo "Rolle '${PG_ROLE}' angelegt."
else
echo "Rolle '${PG_ROLE}' existiert bereits — Passwort wird NICHT neu gesetzt (siehe ${ENV_FILE} fuer das vorhandene)."
PG_PASSWORD=""
fi
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname = '${PG_DB}'" | grep -q 1; then
sudo -u postgres psql -v ON_ERROR_STOP=1 -c "CREATE DATABASE ${PG_DB} OWNER ${PG_ROLE};"
echo "Datenbank '${PG_DB}' angelegt."
else
echo "Datenbank '${PG_DB}' existiert bereits."
fi
# Fuer Tenant-Provisioning (CREATE DATABASE pro Mandant, Modell C) braucht
# die Rolle CREATEDB-Recht auf der physischen Postgres-Instanz.
sudo -u postgres psql -v ON_ERROR_STOP=1 -c "ALTER ROLE ${PG_ROLE} WITH CREATEDB;" >/dev/null
echo "== 3. Secrets/Konfiguration =="
mkdir -p /etc/nexarch
if [ ! -f "$ENV_FILE" ]; then
if [ -z "${PG_PASSWORD}" ]; then
echo "FEHLER: Rolle existierte bereits, aber ${ENV_FILE} fehlt — Passwort kann nicht rekonstruiert werden." >&2
echo "Entweder ${ENV_FILE} von Hand mit dem bekannten Passwort anlegen, oder die Rolle droppen und erneut installieren." >&2
exit 1
fi
AUDIT_ADMIN_TOKEN="$(openssl rand -hex 32)"
# Ed25519-Schluesselpaar fuer die Lizenzsignatur (LIC-01/LIC-04):
# licadmin-devserver prueft Lizenzen nur mit dem OEFFENTLICHEN Schluessel,
# der private Schluessel wird NICHT deployt, sondern separat fuer das
# (noch zu bauende) offline Lizenz-Ausstellungswerkzeug aufbewahrt.
KEYPAIR_DIR=/etc/nexarch/license-signing
mkdir -p "$KEYPAIR_DIR"
chmod 700 "$KEYPAIR_DIR"
if [ ! -f "$KEYPAIR_DIR/private.b64" ]; then
go run "$SCRIPT_DIR/gen-ed25519-keypair.go" > "$KEYPAIR_DIR/keypair.txt"
grep '^PRIVATE=' "$KEYPAIR_DIR/keypair.txt" | cut -d= -f2 > "$KEYPAIR_DIR/private.b64"
grep '^PUBLIC=' "$KEYPAIR_DIR/keypair.txt" | cut -d= -f2 > "$KEYPAIR_DIR/public.b64"
chmod 600 "$KEYPAIR_DIR"/*.b64 "$KEYPAIR_DIR/keypair.txt"
rm -f "$KEYPAIR_DIR/keypair.txt"
fi
LICENSE_PUBLIC_KEY="$(cat "$KEYPAIR_DIR/public.b64")"
cat > "$ENV_FILE" <<EOF
# Automatisch generiert von deploy/install.sh am $(date -Iseconds).
# NICHT ins Repository committen — enthaelt Zugangsdaten/Secrets.
NEXARCH_REGISTRY_DSN=postgresql://${PG_ROLE}:${PG_PASSWORD}@localhost:5432/${PG_DB}?sslmode=disable
NEXARCH_ADMIN_DSN=postgresql://${PG_ROLE}:${PG_PASSWORD}@localhost:5432/postgres?sslmode=disable
NEXARCH_TENANT_DSN_TEMPLATE=postgresql://${PG_ROLE}:${PG_PASSWORD}@localhost:5432/%s?sslmode=disable
NEXARCH_TENANT_SCHEMA_PATH=${INSTALL_DIR}/migrations/tenant
NEXARCH_LISTEN_ADDR=:8080
NEXARCH_AUDIT_ADMIN_TOKEN=${AUDIT_ADMIN_TOKEN}
NEXARCH_LICENSE_PUBLIC_KEY=${LICENSE_PUBLIC_KEY}
EOF
chmod 600 "$ENV_FILE"
chown nexarch:nexarch "$ENV_FILE"
echo "${ENV_FILE} angelegt (Secrets generiert)."
else
echo "${ENV_FILE} existiert bereits — wird nicht ueberschrieben."
fi
echo "== 4. Build =="
mkdir -p "$INSTALL_DIR/bin"
cd "$REPO_ROOT"
for svc in core auditlog-devserver licadmin-devserver metrics-devserver secheaders-devserver statuspage-devserver tenantadmin-devserver; do
go build -o "$INSTALL_DIR/bin/${svc}" "./cmd/${svc}"
echo "gebaut: ${svc}"
done
cp -r migrations "$INSTALL_DIR/migrations"
chown -R nexarch:nexarch "$INSTALL_DIR"
echo "== 5. Registry-Migrationen =="
# shellcheck disable=SC1090
source "$ENV_FILE"
ALREADY_MIGRATED=$(sudo -u postgres psql -tAc "SELECT to_regclass('public.tenants') IS NOT NULL" -d "${PG_DB}")
if [ "$ALREADY_MIGRATED" = "t" ]; then
echo "Registry-Datenbank hat bereits Tabellen — Migrationen werden uebersprungen (nicht idempotent, siehe Skript-Kommentar)."
else
for f in $(find "$INSTALL_DIR/migrations" -maxdepth 1 -name '*.up.sql' | sort); do
sudo -u postgres psql -v ON_ERROR_STOP=1 -d "${PG_DB}" -f "$f" >/dev/null
echo "angewendet: $(basename "$f")"
done
fi
echo "== 6. systemd-Units =="
for tmpl in "$SCRIPT_DIR"/systemd/*.service.tmpl; do
name="$(basename "$tmpl" .service.tmpl)"
sed "s#__INSTALL_DIR__#${INSTALL_DIR}#g" "$tmpl" > "/etc/systemd/system/${name}.service"
done
systemctl daemon-reload
for tmpl in "$SCRIPT_DIR"/systemd/*.service.tmpl; do
name="$(basename "$tmpl" .service.tmpl)"
systemctl enable --now "${name}.service"
done
echo "== Fertig =="
echo "Status pruefen mit: systemctl status 'nexarch-*'"
echo "Health-Checks:"
echo " curl -s http://localhost:8080/healthz"
echo " curl -s http://localhost:8081/healthz # licadmin"
echo " curl -s http://localhost:8082/healthz # tenantadmin"
echo " curl -s http://localhost:8083/healthz # auditlog"
echo " curl -s http://localhost:8084/healthz # statuspage"
echo " curl -s http://localhost:8085/healthz # metrics"
echo " curl -s http://localhost:8086/unprotected # secheaders (kein /healthz)"