#!/usr/bin/env bash set -euo pipefail # === Autorität === COMPOSE_DIR="/opt/hx-ki/com2-stack" COMPOSE_FILE="${COMPOSE_DIR}/docker-compose.yml" ENV_FILE="${COMPOSE_DIR}/.env" # Bind-Mount Pfade (IST-Zustand, von dir geliefert) PG_BIND="/opt/hx-ki/postgres" MY_BIND="/opt/hx-ki/mautic/db" # Container-Namen (IST) PG_C="hxki-postgres" MY_C="hxki-mariadb" TS="$(date +%Y%m%d-%H%M%S)" BK_DIR="/opt/hx-ki/backups/com2-one-shot-${TS}" mkdir -p "$BK_DIR" echo "=== COM2 ONE-SHOT · RECOVER + FIX (no guessing) ===" echo "Compose: $COMPOSE_FILE" echo "Env: $ENV_FILE" echo "Backup: $BK_DIR" echo # --- Preconditions --- [ -f "$COMPOSE_FILE" ] || { echo "FAIL: FEHLT $COMPOSE_FILE"; exit 1; } [ -d "$PG_BIND" ] || { echo "FAIL: FEHLT Postgres Bind $PG_BIND"; exit 1; } [ -d "$MY_BIND" ] || { echo "FAIL: FEHLT MariaDB Bind $MY_BIND"; exit 1; } cp -a "$COMPOSE_FILE" "$BK_DIR/docker-compose.yml.bak" [ -f "$ENV_FILE" ] && cp -a "$ENV_FILE" "$BK_DIR/.env.bak" || true # --- Helper: finde letzte echte Secrets (ohne CHANGE_ME) --- find_last_secret() { local key="$1" local base="/opt/hx-ki" # Suche in .env / compose / backups # Priorität: neueste Datei gewinnt local hit hit="$(find "$base" -maxdepth 6 -type f \ \( -iname ".env" -o -iname "*.env" -o -iname "docker-compose*.yml" -o -iname "*.bak*" -o -iname "*.yml" \) \ -printf '%T@ %p\n' 2>/dev/null \ | sort -nr \ | awk '{print $2}' \ | while read -r f; do # KEY=VALUE Zeile if grep -qE "^${key}=" "$f" 2>/dev/null; then v="$(grep -E "^${key}=" "$f" | tail -n 1 | cut -d= -f2- | tr -d '\r')" # skip empty / placeholder if [ -n "$v" ] && ! echo "$v" | grep -qiE 'CHANGE_ME|CHANGEME|changeme|__REPLACE__'; then echo "$v" exit 0 fi fi done)" || true echo "$hit" } # --- 1) ENV befüllen aus altem Zustand (nur wenn gefunden) --- echo "[1] Recover Secrets aus /opt/hx-ki (no guessing)" PG_PASSWORD="$(find_last_secret "PG_PASSWORD")" MARIADB_ROOT_PASSWORD="$(find_last_secret "MARIADB_ROOT_PASSWORD")" MAUTIC_DB_PASSWORD="$(find_last_secret "MAUTIC_DB_PASSWORD")" # Optional Defaults (nur wenn vorhanden) PG_USER="$(find_last_secret "PG_USER")"; PG_USER="${PG_USER:-hxki}" PG_DB="$(find_last_secret "PG_DB")"; PG_DB="${PG_DB:-n8n}" MAUTIC_DB_USER="$(find_last_secret "MAUTIC_DB_USER")"; MAUTIC_DB_USER="${MAUTIC_DB_USER:-mautic}" MAUTIC_DB_NAME="$(find_last_secret "MAUTIC_DB_NAME")"; MAUTIC_DB_NAME="${MAUTIC_DB_NAME:-mautic}" # N8N Host/Proto (optional) N8N_HOST="$(find_last_secret "N8N_HOST")"; N8N_HOST="${N8N_HOST:-n8n.hx-ki.com}" N8N_PROTOCOL="$(find_last_secret "N8N_PROTOCOL")"; N8N_PROTOCOL="${N8N_PROTOCOL:-https}" missing=0 [ -n "$PG_PASSWORD" ] || { echo "FAIL: PG_PASSWORD nicht gefunden (alter Zustand fehlt)"; missing=1; } [ -n "$MARIADB_ROOT_PASSWORD" ] || { echo "FAIL: MARIADB_ROOT_PASSWORD nicht gefunden (alter Zustand fehlt)"; missing=1; } [ -n "$MAUTIC_DB_PASSWORD" ] || { echo "FAIL: MAUTIC_DB_PASSWORD nicht gefunden (alter Zustand fehlt)"; missing=1; } if [ "$missing" -ne 0 ]; then echo echo "STOP: Ich rate keine Passwörter." echo "Gib mir die alten Values oder lege die alte .env Datei in /opt/hx-ki/ ab." exit 1 fi cat > "$ENV_FILE" <=5 and parts[0] in ("local","host","hostssl","hostnossl"): # method ist letztes token parts[-1]="trust" out.append(" ".join(parts)) else: out.append(line) p.write_text("\n".join(out)+ "\n") PY # Starte nur Postgres docker compose up -d "$PG_C" # Warten bis Postgres bereit for i in $(seq 1 60); do if docker exec -i "$PG_C" sh -lc "pg_isready -U '$PG_USER' -d postgres >/dev/null 2>&1"; then break fi sleep 1 done # Setze Passwort + DB erstellen (wenn fehlt) docker exec -i "$PG_C" sh -lc " psql -U '$PG_USER' -d postgres -v ON_ERROR_STOP=1 </dev/null 2>&1"; then break fi sleep 1 done # Set root pw + mautic user + db docker exec -i "$TMP_C" sh -lc " mysql -uroot </dev/null # normal wieder hoch docker compose up -d "$MY_C" echo "OK: MariaDB repaired (root + mautic user/db)." echo # --- 5) Full stack up + checks --- echo "[5] Orchester up" docker compose up -d --remove-orphans echo echo "=== STATUS ===" docker ps --format 'NAME={{.Names}} STATUS={{.Status}} PORTS={{.Ports}}' | egrep 'hxki-|hx-caddy' || true echo echo "=== CHECKS (DB auth) ===" echo "[A] n8n logs (tail 20)" docker logs --tail=20 hxki-n8n || true echo echo "[B] mautic logs (tail 20)" docker logs --tail=20 hxki-mautic || true echo echo "=== ENDE · ONE-SHOT ==="