Files
siem-backend/deploy.sh
jbergner 9e2f48ceae
Some checks failed
release-tag / release-image (push) Failing after 1m6s
Bugfix 2.0
2026-07-23 17:33:00 +02:00

141 lines
5.3 KiB
Bash
Executable File

#!/usr/bin/env sh
set -eu
cd "$(dirname "$0")"
command -v docker >/dev/null 2>&1 || { echo "Docker fehlt." >&2; exit 1; }
docker compose version >/dev/null 2>&1 || { echo "Docker Compose Plugin fehlt." >&2; exit 1; }
PRESET_ENROLLMENT_KEY="${ENROLLMENT_KEY:-}"
randhex() {
n="$1"
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex "$n"
else
dd if=/dev/urandom bs="$n" count=1 2>/dev/null | od -An -tx1 | tr -d ' \n'
fi
}
get_env() {
key="$1"
awk -F= -v k="$key" '$1==k {sub(/^[^=]*=/, ""); print; exit}' .env 2>/dev/null || true
}
set_env() {
key="$1"; value="$2"; tmp=".env.tmp.$$"
awk -v k="$key" -v v="$value" '
BEGIN {done=0}
index($0,k"=")==1 {print k"="v; done=1; next}
{print}
END {if(!done) print k"="v}
' .env > "$tmp"
mv "$tmp" .env
}
# Start from a complete template, but preserve all values from an existing .env.
[ -f .env ] || : > .env
while IFS= read -r line || [ -n "$line" ]; do
case "$line" in
''|'#'*) continue ;;
esac
key=${line%%=*}
if ! grep -q "^${key}=" .env 2>/dev/null; then
printf '%s\n' "$line" >> .env
fi
done < .env.example
# Generate secrets only if absent/blank/placeholder. Existing installations keep their credentials.
for key in POSTGRES_PASSWORD CLICKHOUSE_PASSWORD UI_PASSWORD GARAGE_SECRET_KEY GARAGE_RPC_SECRET GARAGE_ADMIN_TOKEN GARAGE_METRICS_TOKEN; do
val="$(get_env "$key")"
if [ -z "$val" ] || [ "$val" = "CHANGE_ME" ]; then
case "$key" in
POSTGRES_PASSWORD|CLICKHOUSE_PASSWORD) val="$(randhex 24)" ;;
UI_PASSWORD) val="$(randhex 18)" ;;
*) val="$(randhex 32)" ;;
esac
set_env "$key" "$val"
fi
done
val="$(get_env GARAGE_ACCESS_KEY)"
if [ -z "$val" ] || [ "$val" = "CHANGE_ME" ]; then
set_env GARAGE_ACCESS_KEY "GK$(randhex 16)"
fi
val="$(get_env ENROLLMENT_KEY)"
if [ -n "$PRESET_ENROLLMENT_KEY" ]; then
set_env ENROLLMENT_KEY "$PRESET_ENROLLMENT_KEY"
elif [ -z "$val" ] || [ "$val" = "CHANGE_ME" ]; then
set_env ENROLLMENT_KEY "$(randhex 32)"
fi
chmod 600 .env 2>/dev/null || true
# Validate required settings without sourcing .env as shell code. Docker Compose parses
# .env itself; this also keeps values with shell-special characters safe.
for key in POSTGRES_PASSWORD CLICKHOUSE_PASSWORD UI_PASSWORD ENROLLMENT_KEY GARAGE_ACCESS_KEY GARAGE_SECRET_KEY GARAGE_RPC_SECRET GARAGE_ADMIN_TOKEN GARAGE_METRICS_TOKEN; do
val="$(get_env "$key")"
if [ -z "$val" ] || [ "$val" = "CHANGE_ME" ]; then
echo "Ungültige .env: $key fehlt oder ist noch CHANGE_ME." >&2
exit 1
fi
done
UI_PORT_VALUE="$(get_env UI_PORT)"; [ -n "$UI_PORT_VALUE" ] || UI_PORT_VALUE=8080
INGRESS_PORT_VALUE="$(get_env INGRESS_PORT)"; [ -n "$INGRESS_PORT_VALUE" ] || INGRESS_PORT_VALUE=8090
CLICKHOUSE_USER_VALUE="$(get_env CLICKHOUSE_USER)"; [ -n "$CLICKHOUSE_USER_VALUE" ] || CLICKHOUSE_USER_VALUE=siem
CLICKHOUSE_DB_VALUE="$(get_env CLICKHOUSE_DB)"; [ -n "$CLICKHOUSE_DB_VALUE" ] || CLICKHOUSE_DB_VALUE=siem
CLICKHOUSE_PASSWORD_VALUE="$(get_env CLICKHOUSE_PASSWORD)"
CLICKHOUSE_HTTP_PORT_VALUE="$(get_env CLICKHOUSE_HTTP_PORT)"; [ -n "$CLICKHOUSE_HTTP_PORT_VALUE" ] || CLICKHOUSE_HTTP_PORT_VALUE=8123
CLICKHOUSE_NATIVE_PORT_VALUE="$(get_env CLICKHOUSE_NATIVE_PORT)"; [ -n "$CLICKHOUSE_NATIVE_PORT_VALUE" ] || CLICKHOUSE_NATIVE_PORT_VALUE=9000
UI_USERNAME_VALUE="$(get_env UI_USERNAME)"; [ -n "$UI_USERNAME_VALUE" ] || UI_USERNAME_VALUE=admin
UI_PASSWORD_VALUE="$(get_env UI_PASSWORD)"
ENROLLMENT_KEY_VALUE="$(get_env ENROLLMENT_KEY)"
# Validate the final config before pulling/building anything.
echo "Prüfe Compose-Konfiguration ..."
docker compose config >/dev/null
echo "Baue und starte Greenfield SIEM ..."
docker compose build --pull
docker compose up -d --remove-orphans
http_ok() {
url="$1"
if command -v curl >/dev/null 2>&1; then curl -fsS "$url" >/dev/null 2>&1; return $?; fi
if command -v wget >/dev/null 2>&1; then wget -q -O /dev/null "$url" >/dev/null 2>&1; return $?; fi
return 2
}
echo "Prüfe Readiness ..."
i=0
while [ "$i" -lt 90 ]; do
api_ok=0; ingress_ok=0; ch_ok=0; garage_ok=0
http_ok "http://127.0.0.1:${UI_PORT_VALUE}/readyz" && api_ok=1 || true
http_ok "http://127.0.0.1:${INGRESS_PORT_VALUE}/readyz" && ingress_ok=1 || true
docker compose exec -T clickhouse clickhouse-client --user "${CLICKHOUSE_USER_VALUE}" --password "${CLICKHOUSE_PASSWORD_VALUE}" --query 'SELECT 1' >/dev/null 2>&1 && ch_ok=1 || true
docker compose exec -T garage /garage status >/dev/null 2>&1 && garage_ok=1 || true
if [ "$api_ok" -eq 1 ] && [ "$ingress_ok" -eq 1 ] && [ "$ch_ok" -eq 1 ] && [ "$garage_ok" -eq 1 ]; then
break
fi
i=$((i+1))
sleep 2
done
if [ "$i" -ge 90 ]; then
echo "Mindestens ein Dienst wurde nicht bereit. Diagnose:" >&2
docker compose ps >&2 || true
echo >&2
docker compose logs --tail=120 garage clickhouse clickhouse-schema postgres postgres-schema redpanda redpanda-init ingress processor api >&2 || true
exit 1
fi
echo
echo "Greenfield SIEM läuft."
echo "UI: http://127.0.0.1:${UI_PORT_VALUE}/ui"
echo "Ingress: http://127.0.0.1:${INGRESS_PORT_VALUE}/ingest"
echo "UI-Login: ${UI_USERNAME_VALUE} / ${UI_PASSWORD_VALUE}"
echo "ClickHouse: user=${CLICKHOUSE_USER_VALUE} db=${CLICKHOUSE_DB_VALUE} http=127.0.0.1:${CLICKHOUSE_HTTP_PORT_VALUE} native=127.0.0.1:${CLICKHOUSE_NATIVE_PORT_VALUE}"
echo "Enrollment-Key: ${ENROLLMENT_KEY_VALUE}"
echo "Alle Parameter stehen vollständig in .env."