#!/usr/bin/env bash set -euo pipefail ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) COMPOSE_DIR="$ROOT_DIR/infra/compose" echo "🚀 Dev up: networks, certs, infra, services" # 1) Ensure .env exists if [[ ! -f "$COMPOSE_DIR/.env" ]]; then cp "$COMPOSE_DIR/env.example" "$COMPOSE_DIR/.env" echo "📝 Created .env from template" fi # 2) Read only needed values from .env (do not 'source' due to spaces) get_env() { local key="$1"; local def="${2-}" local line line=$(grep -E "^${key}=" "$COMPOSE_DIR/.env" | tail -n1 || true) if [[ -z "$line" ]]; then printf "%s" "$def"; return; fi printf "%s" "${line#*=}" } DOMAIN=${DOMAIN:-$(get_env DOMAIN local)} AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN:-$(get_env AUTHENTIK_BOOTSTRAP_TOKEN "")} AUTHENTIK_OUTPOST_TOKEN=${AUTHENTIK_OUTPOST_TOKEN:-$(get_env AUTHENTIK_OUTPOST_TOKEN "")} START_APP_SERVICES=${START_APP_SERVICES:-$(get_env START_APP_SERVICES true)} # 3) Networks and certs bash "$ROOT_DIR/scripts/create-networks.sh" bash "$ROOT_DIR/scripts/generate-dev-certs.sh" # 4) Bring up core infra (detached) echo "đŸ—ī¸ Starting Traefik + core infra..." docker compose -f "$COMPOSE_DIR/docker-compose.local.yml" up -d \ ata-traefik ata-authentik-db ata-authentik-redis ata-authentik-server ata-authentik-worker \ ata-vault ata-postgres ata-neo4j ata-qdrant ata-minio ata-redis ata-prometheus ata-grafana ata-loki # 5) Wait for Traefik, then Authentik (initial-setup or login) echo "âŗ Waiting for Traefik to respond..." for i in {1..60}; do code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/ping || true) if [[ "$code" == "200" ]]; then echo "✅ Traefik reachable"; break; fi sleep 2 if [[ "$i" == 60 ]]; then echo "❌ Traefik not ready"; exit 1; fi done echo "âŗ Waiting for Authentik to respond..." AUTH_HOST="auth.${DOMAIN}" RESOLVE=(--resolve "${AUTH_HOST}:443:127.0.0.1") for i in {1..60}; do code_setup=$(curl -ks "${RESOLVE[@]}" -o /dev/null -w '%{http_code}' "https://${AUTH_HOST}/if/flow/initial-setup/" || true) code_login=$(curl -ks "${RESOLVE[@]}" -o /dev/null -w '%{http_code}' "https://${AUTH_HOST}/if/flow/default-authentication-flow/" || true) code_root=$(curl -ks "${RESOLVE[@]}" -o /dev/null -w '%{http_code}' "https://${AUTH_HOST}/" || true) # If initial-setup returns 404 but login/root are healthy, treat as ready (already initialized) if [[ "$code_setup" == "404" ]]; then if [[ "$code_login" =~ ^(200|302|401)$ || "$code_root" =~ ^(200|302|401)$ ]]; then echo "✅ Authentik reachable (initial setup not present)"; break fi fi # If any key flow says OK, proceed if [[ "$code_setup" =~ ^(200|302|401)$ || "$code_login" =~ ^(200|302|401)$ || "$code_root" =~ ^(200|302|401)$ ]]; then echo "✅ Authentik reachable"; break fi sleep 5 if [[ "$i" == 60 ]]; then echo "❌ Authentik not ready"; exit 1; fi done # 6) Setup Authentik (optional automated) if [[ -n "${AUTHENTIK_BOOTSTRAP_TOKEN:-}" ]]; then echo "🔧 Running Authentik setup with bootstrap token..." AUTHENTIK_API_TOKEN="$AUTHENTIK_BOOTSTRAP_TOKEN" DOMAIN="$DOMAIN" bash "$ROOT_DIR/scripts/setup-authentik.sh" || true else echo "â„šī¸ No AUTHENTIK_BOOTSTRAP_TOKEN provided; skipping automated Authentik API setup" fi # 7) Start Authentik outpost if token present if [[ -n "${AUTHENTIK_OUTPOST_TOKEN:-}" && "${AUTHENTIK_OUTPOST_TOKEN}" != "changeme" ]]; then echo "🔐 Starting Authentik outpost..." docker compose -f "$COMPOSE_DIR/docker-compose.local.yml" up -d ata-authentik-outpost || true else echo "â„šī¸ Set AUTHENTIK_OUTPOST_TOKEN in $COMPOSE_DIR/.env to start authentik-outpost" fi # 8) Start application services (optional) if [[ "${START_APP_SERVICES:-true}" == "true" ]]; then echo "🚀 Starting application services..." docker compose -f "$COMPOSE_DIR/docker-compose.local.yml" up -d \ ata-svc-ingestion ata-svc-extract ata-svc-kg ata-svc-rag-retriever ata-svc-coverage \ ata-svc-firm-connectors ata-svc-forms ata-svc-hmrc ata-svc-normalize-map ata-svc-ocr \ ata-svc-rag-indexer ata-svc-reason ata-svc-rpa ata-ui-review ata-unleash || true fi echo "🎉 Dev environment is up" echo "🔗 Traefik dashboard: http://localhost:8080" echo "🔐 Authentik: https://auth.${DOMAIN}" echo "📊 Grafana: https://grafana.${DOMAIN}" echo "📝 Review UI: https://review.${DOMAIN}"