#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" DOCKER_CMD=() SECRETS_FILE="$SCRIPT_DIR/.mongo-secrets.env" RESET_MONGO_DATA=0 for arg in "$@"; do case "$arg" in --reset-mongo-data|-r) RESET_MONGO_DATA=1 ;; esac done ensure_mongo_secrets() { if [ -f "$SECRETS_FILE" ]; then # shellcheck disable=SC1090 source "$SECRETS_FILE" fi if [ -z "${MONGO_INITDB_ROOT_PASSWORD:-}" ]; then MONGO_INITDB_ROOT_PASSWORD="$(openssl rand -hex 24)" fi if [ -z "${MONGO_APP_PASSWORD:-}" ]; then MONGO_APP_PASSWORD="$(openssl rand -hex 24)" fi cat > "$SECRETS_FILE" <&2 return 0 } wait_for_mongo_ready() { local timeout_seconds=180 local interval=2 local elapsed=0 local mongo_container_id="" local container_state="" local health_status="" mongo_container_id="$("${DOCKER_CMD[@]}" compose --env-file "$SECRETS_FILE" ps -q mongodb 2>/dev/null || true)" if [ -z "$mongo_container_id" ]; then echo "[FEHLER] MongoDB-Container wurde nicht gefunden." >&2 return 1 fi while [ $elapsed -lt $timeout_seconds ]; do container_state="$(${DOCKER_CMD[@]} inspect -f '{{.State.Status}} {{if .State.Health}}{{.State.Health.Status}}{{end}}' "$mongo_container_id" 2>/dev/null || true)" health_status="${container_state#* }" if [ "$health_status" = "healthy" ]; then return 0 fi if [ "${container_state%% *}" = "running" ] && [ -z "$health_status" ]; then return 0 fi if [ "${container_state%% *}" = "exited" ] || [ "${container_state%% *}" = "dead" ]; then break fi sleep $interval elapsed=$((elapsed + interval)) done echo "[FEHLER] MongoDB wurde nicht rechtzeitig gestartet. Status: ${container_state:-unbekannt}" >&2 "${DOCKER_CMD[@]}" compose --env-file "$SECRETS_FILE" ps mongodb >&2 || true "${DOCKER_CMD[@]}" compose --env-file "$SECRETS_FILE" logs --tail 80 mongodb >&2 || true return 1 } resolve_docker_cmd() { if docker info >/dev/null 2>&1; then DOCKER_CMD=(docker) return 0 fi if sudo -n docker info >/dev/null 2>&1; then DOCKER_CMD=(sudo docker) return 0 fi if command -v sudo >/dev/null 2>&1 && [ -t 0 ]; then echo "Docker-Zugriff ohne Gruppe erkannt. Verwende sudo docker (ggf. Passwortabfrage)." if sudo docker info >/dev/null 2>&1; then DOCKER_CMD=(sudo docker) return 0 fi fi echo "[FEHLER] Kein Zugriff auf den Docker Daemon (/var/run/docker.sock)." >&2 echo "Führe das Script mit sudo aus oder füge deinen User zur docker-Gruppe hinzu:" >&2 echo " sudo usermod -aG docker $USER" >&2 echo "Danach neu einloggen und Script erneut starten." >&2 exit 3 } compose() { "${DOCKER_CMD[@]}" compose --env-file "$SECRETS_FILE" "$@" } is_truthy() { case "${1:-}" in 1|true|TRUE|yes|YES|on|ON) return 0 ;; *) return 1 ;; esac } reset_mongo_data_if_requested() { if ! is_truthy "${MONGO_RESET_DATA:-0}" && [ "$RESET_MONGO_DATA" -ne 1 ]; then return 0 fi echo "[WARNUNG] Setze den MongoDB-Volume-Stand zurück, damit die aktuellen Secrets neu initialisiert werden." >&2 "${DOCKER_CMD[@]}" compose --env-file "$SECRETS_FILE" down -v --remove-orphans } build_website_image() { if compose build website; then return 0 fi echo "[WARNUNG] Standard-Build fehlgeschlagen, versuche Legacy-Build ohne BuildKit erneut..." >&2 DOCKER_BUILDKIT=0 COMPOSE_DOCKER_CLI_BUILD=0 compose build website } export SESSION_COOKIE_SECURE="0" export INSTANCE_TLS_MODE="development" export INSTANCE_PARENT_DOMAIN="${INSTANCE_PARENT_DOMAIN:-meine-domain}" export DEV_HOSTS_REFRESH_INTERVAL="${DEV_HOSTS_REFRESH_INTERVAL:-30}" echo "Launching WEBSITE stack" echo " SESSION_COOKIE_SECURE=$SESSION_COOKIE_SECURE" echo " INSTANCE_TLS_MODE=$INSTANCE_TLS_MODE" echo " INSTANCE_PARENT_DOMAIN=$INSTANCE_PARENT_DOMAIN" echo " DEV_HOSTS_REFRESH_INTERVAL=$DEV_HOSTS_REFRESH_INTERVAL" ensure_mongo_secrets # Ensure required runtime files exist before building if [ ! -f "$SCRIPT_DIR/gunicorn.conf.py" ]; then echo "[FEHLER] gunicorn.conf.py fehlt in $SCRIPT_DIR. Bitte prüfen." >&2 exit 2 fi resolve_docker_cmd reset_mongo_data_if_requested build_website_image compose up -d mongodb wait_for_mongo_ready ensure_mongo_app_user compose up -d --no-deps website # Wait for website to become healthy (simple HTTP check) check_url="http://localhost:4999" timeout_seconds=60 interval=2 elapsed=0 echo "Warte auf Website (${check_url}) bis ${timeout_seconds}s..." while [ $elapsed -lt $timeout_seconds ]; do if curl -sS --max-time 2 "$check_url" >/dev/null 2>&1; then echo "Website erreichbar nach ${elapsed}s" break fi sleep $interval elapsed=$((elapsed + interval)) done if [ $elapsed -ge $timeout_seconds ]; then echo "[FEHLER] Website nicht erreichbar nach ${timeout_seconds}s. Sammle Diagnosedaten..." echo "--- docker compose ps ---" compose ps || true echo "--- docker logs website (tail 200) ---" "${DOCKER_CMD[@]}" logs --tail 200 website-website-1 || true echo "Bitte prüfe Container-Logs und nginx-Konfiguration." fi echo "Website stack is running on http://localhost:4999" echo "Provisioning creates self-signed certs per subdomain when needed."