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

View File

@@ -0,0 +1,232 @@
#!/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" <<ENV
PG_USER=${PG_USER}
PG_PASSWORD=${PG_PASSWORD}
PG_DB=${PG_DB}
MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
MAUTIC_DB_USER=${MAUTIC_DB_USER}
MAUTIC_DB_PASSWORD=${MAUTIC_DB_PASSWORD}
MAUTIC_DB_NAME=${MAUTIC_DB_NAME}
N8N_HOST=${N8N_HOST}
N8N_PROTOCOL=${N8N_PROTOCOL}
ENV
echo "OK: .env konsistent aus altem Zustand gesetzt."
echo
# --- 2) Stack runter (sauber) ---
echo "[2] Orchester down"
cd "$COMPOSE_DIR"
docker compose down --remove-orphans || true
# --- 3) Postgres: PW + DB fix via temporär trust (bind-mount pg_hba.conf) ---
echo "[3] Postgres Repair (bind-mount, deterministisch)"
PG_HBA="${PG_BIND}/pg_hba.conf"
[ -f "$PG_HBA" ] || { echo "FAIL: FEHLT $PG_HBA"; exit 1; }
cp -a "$PG_HBA" "$BK_DIR/pg_hba.conf.bak"
# Setze ALLE host/local auf trust (temporär), damit wir ohne Passwort reinkommen
# Danach setzen wir wieder auf scram-sha-256 zurück.
python3 - <<'PY'
from pathlib import Path
p = Path("/opt/hx-ki/postgres/pg_hba.conf")
s = p.read_text()
out=[]
for line in s.splitlines():
if line.strip().startswith("#") or line.strip()=="":
out.append(line); continue
parts=line.split()
if len(parts)>=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 <<SQL
DO \$\$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_database WHERE datname='${PG_DB}') THEN
CREATE DATABASE \"${PG_DB}\";
END IF;
END
\$\$;
ALTER ROLE \"${PG_USER}\" WITH PASSWORD '${PG_PASSWORD}';
SQL
"
# Restore pg_hba.conf (Original wiederherstellen)
cp -a "$BK_DIR/pg_hba.conf.bak" "$PG_HBA"
# Restart Postgres (scram wieder aktiv)
docker compose restart "$PG_C"
echo "OK: Postgres repaired (PW + DB) und auth wieder wie vorher."
echo
# --- 4) MariaDB: root + mautic-user fix via temporary skip-grant-tables ---
echo "[4] MariaDB Repair (bind-mount, deterministisch)"
# Stop mariadb, starte temporär mit skip-grant-tables (nur lokal im container)
docker compose stop "$MY_C" || true
TMP_C="hxki-mariadb-repair-${TS}"
# gleicher bind mount, aber ohne Auth
docker run -d --rm \
--name "$TMP_C" \
-v "${MY_BIND}:/var/lib/mysql" \
--network none \
mariadb:latest \
--skip-grant-tables --skip-networking
# warten bis mysqld da ist
for i in $(seq 1 60); do
if docker exec -i "$TMP_C" sh -lc "mysqladmin ping --silent >/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 <<SQL
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MARIADB_ROOT_PASSWORD}';
CREATE DATABASE IF NOT EXISTS \`${MAUTIC_DB_NAME}\`;
CREATE USER IF NOT EXISTS '${MAUTIC_DB_USER}'@'%' IDENTIFIED BY '${MAUTIC_DB_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${MAUTIC_DB_NAME}\`.* TO '${MAUTIC_DB_USER}'@'%';
FLUSH PRIVILEGES;
SQL
"
docker stop "$TMP_C" >/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 ==="