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

33
com-stack/caddy/Caddyfile Normal file
View File

@@ -0,0 +1,33 @@
{
email admin@hx-ki.com
}
# === N8N =====================================================
n8n.hx-ki.com {
reverse_proxy hxki-n8n:5678
}
# === GRAFANA ================================================
grafana.hx-ki.com {
reverse_proxy hxki-grafana:3000
}
# === MAUTIC =================================================
mautic.hx-ki.com {
reverse_proxy hxki-mautic:80
}
# === GITEA ==================================================
gitea.hx-ki.com {
reverse_proxy hxki-gitea:3000
}
# === WEBUI ==================================================
app.hx-ki.com {
reverse_proxy hxki-web:3000
}
# === TEST / LEBENSZEICHEN ===================================
caddy.hx-ki.com {
respond "HX-KI COM Server läuft (Ferrari-Modus aktiviert)." 200
}

35
com-stack/com2_restore.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail
STACK_DIR="/opt/hx-ki/com-stack"
COMPOSE="$STACK_DIR/docker-compose.yml"
NET="hxki-internal"
echo "=== HXKI · COM2 RESTORE (Autorität: $COMPOSE) ==="
[ -f "$COMPOSE" ] || { echo "FEHLT: $COMPOSE"; exit 1; }
# Host-Caddy killen, damit Docker-Caddy 80/443 bekommt
if systemctl is-active --quiet caddy 2>/dev/null; then
echo "[1] Stoppe host-caddy (systemd)"
systemctl stop caddy
fi
# Netzwerk sicherstellen
if ! docker network ls --format '{{.Name}}' | grep -q "^$NET$"; then
echo "[2] Erzeuge Netzwerk $NET"
docker network create "$NET"
fi
echo "[3] COM2 Orchester: down/up über Compose"
cd "$STACK_DIR"
docker compose down
docker compose up -d --remove-orphans
echo "[4] Container"
docker ps --format 'NAME={{.Names}} STATUS={{.Status}} PORTS={{.Ports}}'
echo "[5] hxki-internal Mitglieder"
docker network inspect "$NET" --format '{{range $id,$c := .Containers}}{{println $c.Name}}{{end}}' | sort
echo "=== ENDE · COM2 RESTORE ==="

View File

@@ -0,0 +1,92 @@
version: "3.9"
networks:
hxki-internal:
external: true
services:
# ========== CADDY (Reverse Proxy mit SSL) ==========
caddy:
image: caddy:latest
container_name: hx-caddy
restart: unless-stopped
networks:
- hxki-internal
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
# ========== N8N (Master Instanz) ==========
hxki-n8n:
image: docker.n8n.io/n8nio/n8n
container_name: hxki-n8n
restart: unless-stopped
networks:
- hxki-internal
environment:
- N8N_BASIC_AUTH_ACTIVE=false
- N8N_DIAGNOSTICS_ENABLED=false
- N8N_HOST=n8n.hx-ki.com
- N8N_PORT=5678
- N8N_EDITOR_BASE_URL=https://n8n.hx-ki.com
- WEBHOOK_URL=https://n8n.hx-ki.com
volumes:
- /data/HXKI_WORKSPACE/router:/home/node/.n8n
- /data/HXKI_WORKSPACE:/data/HXKI_WORKSPACE
# ========== Grafana ==========
hxki-grafana:
image: grafana/grafana:latest
container_name: hxki-grafana
restart: unless-stopped
networks:
- hxki-internal
volumes:
- grafana_data:/var/lib/grafana
# ========== Postgres ==========
hxki-postgres:
image: postgres:15
container_name: hxki-postgres
restart: unless-stopped
environment:
POSTGRES_PASSWORD: "hxki_password"
networks:
- hxki-internal
volumes:
- postgres_data:/var/lib/postgresql/data
# ========== MariaDB ==========
hxki-mariadb:
image: mariadb:10.11
container_name: hxki-mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "hxki_password"
networks:
- hxki-internal
volumes:
- mariadb_data:/var/lib/mysql
# ========== WebUI ==========
hxki-web:
image: node:18
container_name: hxki-web
networks:
- hxki-internal
command: >
bash -c "cd /app && npm install && npm run start"
volumes:
- ./web:/app
volumes:
grafana_data:
postgres_data:
mariadb_data:
caddy_data:
caddy_config:

View File

@@ -0,0 +1,92 @@
version: "3.9"
networks:
hxki-internal:
external: true
services:
# ========== CADDY (Reverse Proxy mit SSL) ==========
caddy:
image: caddy:latest
container_name: hx-caddy
restart: unless-stopped
networks:
- hxki-internal
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
# ========== N8N (Master Instanz) ==========
hxki-n8n:
image: docker.n8n.io/n8nio/n8n
container_name: hxki-n8n
restart: unless-stopped
networks:
- hxki-internal
environment:
- N8N_BASIC_AUTH_ACTIVE=false
- N8N_DIAGNOSTICS_ENABLED=false
- N8N_HOST=n8n.hx-ki.com
- N8N_PORT=5678
- N8N_EDITOR_BASE_URL=https://n8n.hx-ki.com
- WEBHOOK_URL=https://n8n.hx-ki.com
volumes:
- /data/HXKI_WORKSPACE/router:/home/node/.n8n
- /data/HXKI_WORKSPACE:/data/HXKI_WORKSPACE
# ========== Grafana ==========
hxki-grafana:
image: grafana/grafana:latest
container_name: hxki-grafana
restart: unless-stopped
networks:
- hxki-internal
volumes:
- grafana_data:/var/lib/grafana
# ========== Postgres ==========
hxki-postgres:
image: postgres:15
container_name: hxki-postgres
restart: unless-stopped
environment:
POSTGRES_PASSWORD: "hxki_password"
networks:
- hxki-internal
volumes:
- postgres_data:/var/lib/postgresql/data
# ========== MariaDB ==========
hxki-mariadb:
image: mariadb:10.11
container_name: hxki-mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "hxki_password"
networks:
- hxki-internal
volumes:
- mariadb_data:/var/lib/mysql
# ========== WebUI ==========
hxki-web:
image: node:18
container_name: hxki-web
networks:
- hxki-internal
command: >
bash -c "cd /app && npm install && npm run start"
volumes:
- ./web:/app
volumes:
grafana_data:
postgres_data:
mariadb_data:
caddy_data:
caddy_config:

45
com-stack/hxki_fix_n8n_perms.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
C="hxki-n8n"
DEST="/home/node/.n8n"
echo "=== HXKI FIX n8n PERMS ==="
# Container muss existieren (auch wenn er crasht)
docker inspect "$C" >/dev/null 2>&1 || { echo "FEHLT: Container $C"; exit 1; }
# Mount-Quelle für /home/node/.n8n bestimmen
SRC="$(docker inspect "$C" --format '{{range .Mounts}}{{if eq .Destination "'"$DEST"'"}}{{println .Source}}{{end}}{{end}}' | head -n1)"
[[ -n "${SRC:-}" ]] || { echo "FEHLT: Kein Mount auf $DEST gefunden."; exit 1; }
echo "Mount: $SRC -> $DEST"
# Image bestimmen (für UID/GID, falls Container nicht exec-fähig ist)
IMG="$(docker inspect "$C" --format '{{.Config.Image}}')"
echo "Image: $IMG"
# UID/GID aus dem Image holen (funktioniert auch wenn Container restartet)
N8N_UID="$(docker run --rm --entrypoint sh "$IMG" -lc 'id -u node 2>/dev/null || id -u' )"
N8N_GID="$(docker run --rm --entrypoint sh "$IMG" -lc 'id -g node 2>/dev/null || id -g' )"
echo "Ziel-Owner: $N8N_UID:$N8N_GID"
# Container stoppen (damit keine Writes während chown)
echo "Stoppe $C..."
docker stop "$C" >/dev/null 2>&1 || true
# Rechte setzen
echo "Setze Owner/Rechte auf Host-Pfad: $SRC"
chown -R "$N8N_UID:$N8N_GID" "$SRC"
chmod -R u+rwX,g+rwX "$SRC"
# Container starten
echo "Starte $C..."
docker start "$C" >/dev/null 2>&1 || true
echo "Status:"
docker ps --format 'NAME={{.Names}} STATUS={{.Status}}' | grep "$C" || true
echo "Letzte Logs:"
docker logs --tail=30 "$C" || true
echo "=== ENDE ==="

23
com-stack/orchestra_up.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
cd /opt/hx-ki/com-stack
docker compose up -d --remove-orphans
# 90 Sekunden Health-Gate (anpassen)
deadline=$((SECONDS+90))
while (( SECONDS < deadline )); do
bad=$(docker ps --format '{{.Names}} {{.Status}}' | egrep 'unhealthy|Restarting' || true)
if [[ -z "$bad" ]]; then
echo "OK: Orchester stabil."
exit 0
fi
echo "WARTEN: noch nicht stabil:"
echo "$bad"
sleep 3
done
echo "FAIL: nicht stabil -> fahre alles runter (alle oder keiner)."
docker compose down
exit 1

6
com-stack/web/package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "app",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}