#!/usr/bin/env bash set -euo pipefail DIR="/opt/hx-ki/com2-stack" F="$DIR/docker-compose.yml" ENVF="$DIR/.env" NET="hxki-internal" TS="$(date +%Y%m%d-%H%M%S)" BK="/opt/hx-ki/backups/com2-repair-$TS" mkdir -p "$BK" echo "=== COM2 REPAIR · CANONICAL ONE-SHOT (no guessing) ===" echo "Compose: $F" echo "Env: $ENVF" echo "Backup: $BK" echo [ -f "$F" ] || { echo "FAIL: FEHLT $F"; exit 1; } cp -a "$F" "$BK/docker-compose.yml.pre" # 0) Netzwerk sicherstellen (external) docker network inspect "$NET" >/dev/null 2>&1 || docker network create "$NET" >/dev/null # 1) Alte Secrets/DB-Namen aus vorhandenen Dateien RECOVERn (keine Fantasie) # Priorität: Inventory/Backups -> dann bestehende .env echo "[1] Recover old state (secrets/dbnames) from /opt/hx-ki …" # helper: first match from file list first_match() { local re="$1"; shift; for f in "$@"; do [ -f "$f" ] || continue; local v; v="$(grep -Eo "$re" "$f" | head -n1 || true)"; [ -n "$v" ] && { echo "$v"; return 0; }; done; return 1; } # Kandidatenquellen (du hast sie bereits im System) SRC_FILES=( "/opt/hx-ki/inventory/"*.txt "/opt/hx-ki/com2-stack/"*.bak.* "/opt/hx-ki/com-stack/docker-compose.yml" "/opt/hx-ki/com-stack/"*.bak.* "/opt/hx-ki/docker/"docker-compose.yml* "$ENVF" ) # Postgres: Passwort + DB PG_PASS_LINE="$(first_match 'POSTGRES_PASSWORD=[^[:space:]]+' "${SRC_FILES[@]}" || true)" PG_DB_LINE="$(first_match 'POSTGRES_DB=[^[:space:]]+' "${SRC_FILES[@]}" || true)" PG_USER_LINE="$(first_match 'POSTGRES_USER=[^[:space:]]+' "${SRC_FILES[@]}" || true)" # Mautic/MariaDB: root oder mautic creds MY_ROOT_LINE="$(first_match '(MARIADB_ROOT_PASSWORD|MYSQL_ROOT_PASSWORD)=[^[:space:]]+' "${SRC_FILES[@]}" || true)" MAUTIC_USER_LINE="$(first_match 'MAUTIC_DB_USER=[^[:space:]]+' "${SRC_FILES[@]}" || true)" MAUTIC_PASS_LINE="$(first_match 'MAUTIC_DB_PASSWORD=[^[:space:]]+' "${SRC_FILES[@]}" || true)" MAUTIC_NAME_LINE="$(first_match 'MAUTIC_DB_NAME=[^[:space:]]+' "${SRC_FILES[@]}" || true)" MAUTIC_ROOT_LINE="$(first_match 'MAUTIC_DB_ROOT_PASSWORD=[^[:space:]]+' "${SRC_FILES[@]}" || true)" # Minimalanforderungen if [ -z "${PG_PASS_LINE:-}" ] || [ -z "${PG_DB_LINE:-}" ] || [ -z "${PG_USER_LINE:-}" ]; then echo "FAIL: Postgres Altzustand nicht eindeutig (POSTGRES_USER/PASSWORD/DB)." echo " Liefere eine Quelle mit diesen Keys (inventory txt oder altes .env)." exit 1 fi # MariaDB/Mautic: entweder ROOT oder MAUTIC_* muss vorhanden sein if [ -z "${MY_ROOT_LINE:-}" ] && [ -z "${MAUTIC_ROOT_LINE:-}" ] && ( [ -z "${MAUTIC_USER_LINE:-}" ] || [ -z "${MAUTIC_PASS_LINE:-}" ] ); then echo "FAIL: MariaDB/Mautic Altzustand nicht eindeutig (root oder mautic creds fehlen)." exit 1 fi echo " OK Postgres: $PG_USER_LINE $PG_DB_LINE (PW recovered)" echo " OK MariaDB: $( [ -n "${MY_ROOT_LINE:-}" ] && echo "$MY_ROOT_LINE" || echo "$MAUTIC_ROOT_LINE" ) (root PW recovered)" echo # 2) Schreibe .env KANONISCH (nur Werte, die wir wirklich kennen) echo "[2] Write canonical .env (aligned to old DB state)" cp -a "${ENVF:-/dev/null}" "$BK/.env.pre" 2>/dev/null || true PG_USER="${PG_USER_LINE#POSTGRES_USER=}" PG_PASSWORD="${PG_PASS_LINE#POSTGRES_PASSWORD=}" PG_DB="${PG_DB_LINE#POSTGRES_DB=}" # Mautic Defaults (wenn nicht vorhanden, bleiben leer -> Compose muss dann nicht drauf referenzieren) MAUTIC_DB_USER="${MAUTIC_USER_LINE#MAUTIC_DB_USER=}" MAUTIC_DB_PASSWORD="${MAUTIC_PASS_LINE#MAUTIC_DB_PASSWORD=}" MAUTIC_DB_NAME="${MAUTIC_NAME_LINE#MAUTIC_DB_NAME=}" MAUTIC_DB_ROOT_PASSWORD="${MAUTIC_ROOT_LINE#MAUTIC_DB_ROOT_PASSWORD=}" # root pw aus MARIADB_ROOT_PASSWORD falls vorhanden if [ -n "${MY_ROOT_LINE:-}" ]; then ROOTPW="${MY_ROOT_LINE#*=}" else ROOTPW="${MAUTIC_DB_ROOT_PASSWORD:-}" fi cat > "$ENVF" </dev/null echo " OK: compose valid" # 4) Orchester hoch echo "[4] Up" cd "$DIR" docker compose --env-file "$ENVF" down --remove-orphans || true docker compose --env-file "$ENVF" up -d --remove-orphans # 5) Hard checks: DB login, then services listen, then caddy->upstreams echo echo "[5] HARD CHECKS" echo "--- Postgres auth check (inside container) ---" docker exec -e PGPASSWORD="$PG_PASSWORD" -it hxki-postgres psql -U "$PG_USER" -d "$PG_DB" -c "SELECT 1;" >/dev/null && echo "OK_PG_AUTH" || echo "FAIL_PG_AUTH" echo "--- MariaDB auth check (inside container) ---" docker exec -it hxki-mariadb sh -lc "mysql -uroot -p'$ROOTPW' -e 'SELECT 1;' >/dev/null 2>&1 && echo OK_MY_AUTH || echo FAIL_MY_AUTH" echo "--- n8n logs (tail) ---" docker logs --tail=20 hxki-n8n || true echo "--- mautic logs (tail) ---" docker logs --tail=40 hxki-mautic || true echo "--- caddy -> upstreams ---" 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 docker exec -it hx-caddy sh -lc "wget -qO- http://hxki-mautic/ >/dev/null && echo OK_CADDY_TO_MAUTIC || echo FAIL_CADDY_TO_MAUTIC" || true echo echo "=== DONE ===" echo "Backup: $BK"