initial COM2 system snapshot

This commit is contained in:
gitea
2026-03-06 15:22:40 +00:00
commit 9c0fa49baf
4377 changed files with 273033 additions and 0 deletions

137
COM2_DOCTOR_ONE_SHOT.sh Executable file
View File

@@ -0,0 +1,137 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="/opt/hx-ki/com2-stack"
F="$DIR/docker-compose.yml"
NET="hxki-internal"
TS="$(date +%Y%m%d-%H%M%S)"
BK="$DIR/backup-$TS"
echo "=== COM2 DOCTOR (one-shot, deterministisch) ==="
echo "Autorität: $F"
echo "Backup: $BK"
mkdir -p "$BK"
# 0) Preconditions
[ -f "$F" ] || { echo "FEHLT: $F"; exit 1; }
cp -a "$F" "$BK/docker-compose.yml.orig"
# 1) Host-Caddy darf NICHT Port 80/443 blocken, wenn Docker-Caddy laufen soll
if systemctl is-active --quiet caddy 2>/dev/null; then
echo "[1] Stoppe host-caddy (systemd), damit Docker-Caddy 80/443 bekommt"
systemctl stop caddy
else
echo "[1] OK: host-caddy ist nicht aktiv"
fi
# 2) Docker Netzwerk sicherstellen (external)
docker network inspect "$NET" >/dev/null 2>&1 || { echo "[2] Erzeuge Docker-Netzwerk: $NET"; docker network create "$NET" >/dev/null; }
echo "[2] OK: Netzwerk existiert: $NET"
# 3) Compose YAML MUSS valide sein sonst: Restore und STOP mit Zeilenanzeige
echo "[3] Validate Compose YAML"
if ! docker compose -f "$F" config >/dev/null 2>&1; then
echo "FAIL: Compose ist NICHT valide."
echo "---- Parser-Fehler ----"
docker compose -f "$F" config 2>&1 | tail -n 30 || true
echo "---- Zeilen um die vermutete Fehlerstelle (45-80) ----"
nl -ba "$F" | sed -n '45,80p' || true
echo
echo "Auto-Restore auf Backup und STOP."
cp -a "$BK/docker-compose.yml.orig" "$F"
exit 1
fi
echo "[3] OK: Compose ist valide"
# 4) Pflicht-Services auf COM2 (laut deiner Vorgabe: autark)
echo "[4] Prüfe Pflicht-Services im Compose (ohne Umbau)"
python3 - <<'PY'
import re, pathlib, sys
p = pathlib.Path("/opt/hx-ki/com2-stack/docker-compose.yml")
s = p.read_text()
m = re.search(r'(?ms)^services:\s*\n(.*?)(?=^\S|\Z)', s)
if not m:
print("FAIL: Kein Top-Level 'services:' Block.")
sys.exit(1)
block = m.group(1)
names = re.findall(r'(?m)^\s{2}([A-Za-z0-9_.-]+):\s*$', block)
need = ["hx-caddy","hxki-n8n","hxki-postgres","hxki-mariadb","hxki-mautic"]
missing = [x for x in need if x not in names]
print("Services gefunden:", ", ".join(names))
if missing:
print("FAIL: Pflicht-Services fehlen:", ", ".join(missing))
sys.exit(2)
print("OK: Pflicht-Services vorhanden.")
PY
# 5) hxki-internal als external:true MUSS im Compose vorhanden sein (sonst knallt network-ref)
echo "[5] Prüfe: networks/hxki-internal external:true"
python3 - <<'PY'
from pathlib import Path
import re, sys
p = Path("/opt/hx-ki/com2-stack/docker-compose.yml")
s = p.read_text()
# sehr konservativ: nur prüfen, nicht "raten"
if not re.search(r'(?ms)^networks:\s*\n(?:.*\n)*?\s{2}hxki-internal:\s*\n(?:.*\n)*?\s{4}external:\s*true\s*$', s):
print("FAIL: networks: hxki-internal: external:true fehlt oder ist anders.")
print("Zeilen-Hinweis:")
import subprocess, shlex
subprocess.run(["bash","-lc",f"nl -ba {p} | grep -nE '^(\\s*networks:|\\s{{2}}hxki-internal:|\\s{{4}}external:)' -n || true"])
sys.exit(3)
print("OK: networks/hxki-internal external:true gefunden.")
PY
# 6) n8n config MUSS gültiges JSON sein (dein log beweist, dass es kaputt war)
# Wir reparieren NUR das deterministisch: config als JSON resetten, ohne Workflows/DB anzufassen.
echo "[6] Fix: n8n config JSON (nur wenn kaputt)"
MOUNT_SRC="/data/HXKI_WORKSPACE/router"
CFG="$MOUNT_SRC/config"
if [ -d "$MOUNT_SRC" ]; then
docker stop hxki-n8n >/dev/null 2>&1 || true
if [ -f "$CFG" ]; then
if python3 - <<PY >/dev/null 2>&1
import json
json.load(open("$CFG","r"))
PY
then
echo "OK: $CFG ist gültiges JSON (nichts zu tun)"
else
echo "WARN: $CFG ist KEIN gültiges JSON -> schreibe minimal gültig + Backup"
cp -a "$CFG" "$CFG.bak.$TS"
cat > "$CFG" <<JSON
{"encryptionKey":"","instanceId":""}
JSON
chown 1000:1000 "$CFG" || true
chmod 600 "$CFG" || true
fi
else
echo "INFO: $CFG existiert nicht -> wird von n8n beim Start erzeugt"
fi
# Rechte auf Mount (konservativ)
chown -R 1000:1000 "$MOUNT_SRC" || true
chmod -R u+rwX "$MOUNT_SRC" || true
chmod -R g+rwX "$MOUNT_SRC" || true
docker start hxki-n8n >/dev/null 2>&1 || true
else
echo "WARN: $MOUNT_SRC fehlt -> n8n Mount passt nicht (keine Reparatur)"
fi
# 7) Orchester hoch (alles oder nichts)
echo "[7] Orchester UP (alles zusammen)"
cd "$DIR"
docker compose up -d --remove-orphans
echo "[8] Status (Container)"
docker ps --format 'NAME={{.Names}} STATUS={{.Status}} PORTS={{.Ports}}' | egrep 'hxki-|hx-' || true
echo "[9] Netzwerk-Mitglieder: $NET"
docker network inspect "$NET" --format '{{range $id,$c := .Containers}}{{println $c.Name}}{{end}}' | sort || true
# 10) Caddy -> n8n intern test (nur intern, ohne "lokal 127.0.0.1")
echo "[10] Caddy->n8n Service-Test (intern)"
docker exec -it hx-caddy sh -lc 'wget -qO- http://hxki-n8n:5678/ >/dev/null && echo OK_CADDY_TO_N8N || echo FAIL_CADDY_TO_N8N' || true
echo "=== ENDE ==="