services:
  postgres_ory:
    image: postgres:${ORY_POSTGRES_TAG:-17-alpine}
    container_name: ory_postgres
    environment:
      - POSTGRES_USER=${ORY_POSTGRES_USER:-ory}
      - POSTGRES_PASSWORD=${ORY_POSTGRES_PASSWORD:-secret}
      - POSTGRES_DB=${ORY_POSTGRES_DB:-ory}
    volumes:
      - ./docker/ory/init-db:/docker-entrypoint-initdb.d
      - ory_postgres_data:/var/lib/postgresql/data
    networks:
      - ory-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${ORY_POSTGRES_USER:-ory} -d ${KRATOS_DB:-ory_kratos}"]
      interval: 5s
      timeout: 5s
      retries: 5

  # --- Kratos ---
  kratos-migrate:
    image: oryd/kratos:${KRATOS_VERSION:-v25.4.0}
    environment:
      - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KRATOS_DB}?sslmode=disable&max_conns=20
      - KRATOS_SERVE_PUBLIC_BASE_URL=${KRATOS_BROWSER_URL:-http://localhost:4433}
      - KRATOS_SERVE_ADMIN_BASE_URL=${KRATOS_ADMIN_URL:-http://kratos:4434}
      - KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL:-http://localhost:4455}
      - KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=["${KRATOS_UI_URL:-http://localhost:4455}","${USERFRONT_URL:-http://localhost:5000}"]
      - KRATOS_SELFSERVICE_FLOWS_ERROR_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/error
      - KRATOS_SELFSERVICE_FLOWS_SETTINGS_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/settings
      - KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/recovery
      - KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/verification
      - KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/login
      - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/registration
      - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL:-http://localhost:4455}/login
    volumes:
      - ./docker/ory/kratos:/etc/config/kratos
    command: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
    depends_on:
      postgres_ory:
        condition: service_healthy
    networks:
      - ory-net

  kratos:
    image: oryd/kratos:${KRATOS_VERSION:-v25.4.0}
    container_name: ory_kratos
    ports:
      - "${KRATOS_PUBLIC_PORT:-4433}:4433"
    environment:
      - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KRATOS_DB}?sslmode=disable&max_conns=20
      - COOKIE_SECRET=${COOKIE_SECRET:-localcookie123}
      - KRATOS_SERVE_PUBLIC_BASE_URL=${KRATOS_BROWSER_URL:-http://localhost:4433}
      - KRATOS_SERVE_ADMIN_BASE_URL=${KRATOS_ADMIN_URL:-http://kratos:4434}
      - KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL:-http://localhost:4455}
      - KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=["${KRATOS_UI_URL:-http://localhost:4455}","${USERFRONT_URL:-http://localhost:5000}"]
      - KRATOS_SELFSERVICE_FLOWS_ERROR_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/error
      - KRATOS_SELFSERVICE_FLOWS_SETTINGS_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/settings
      - KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/recovery
      - KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/verification
      - KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/login
      - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL:-http://localhost:4455}/registration
      - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL:-http://localhost:4455}/login
    volumes:
      - ./docker/ory/kratos:/etc/config/kratos
    command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
    depends_on:
      kratos-migrate:
        condition: service_completed_successfully
    networks:
      - ory-net
      - kratosnet

  kratos-ui:
    image: oryd/kratos-selfservice-ui-node:${KRATOS_UI_NODE_VERSION:-v25.4.0}
    container_name: ory_kratos_ui
    environment:
      - KRATOS_PUBLIC_URL=${KRATOS_PUBLIC_URL:-http://kratos:4433/}
      - KRATOS_BROWSER_URL=${KRATOS_BROWSER_URL:-http://localhost:${KRATOS_PUBLIC_PORT:-4433}}
      - KRATOS_ADMIN_URL=${KRATOS_ADMIN_URL:-http://kratos:4434/}
      - NODE_ENV=development
      - PORT=${KRATOS_UI_PORT:-4455}
      - COOKIE_SECRET=${COOKIE_SECRET}
      - CSRF_COOKIE_NAME=${CSRF_COOKIE_NAME}
      - CSRF_COOKIE_SECRET=${CSRF_COOKIE_SECRET}
    networks:
      - ory-net

  # --- Hydra ---
  hydra-migrate:
    image: oryd/hydra:${HYDRA_VERSION:-v25.4.0}
    environment:
      - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${HYDRA_DB}?sslmode=disable&max_conns=20
    command: migrate sql -e --yes
    depends_on:
      postgres_ory:
        condition: service_healthy
    networks:
      - ory-net

  hydra:
    image: oryd/hydra:${HYDRA_VERSION:-v25.4.0}
    container_name: ory_hydra
    environment:
      - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${HYDRA_DB}?sslmode=disable&max_conns=20
      - URLS_SELF_ISSUER=${BACKEND_URL:-http://127.0.0.1:3000}
      - URLS_LOGIN=${BACKEND_URL:-http://127.0.0.1:3000}/login
      - URLS_CONSENT=${BACKEND_URL:-http://127.0.0.1:3000}/consent
      - SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD}
    volumes:
      - ./docker/ory/hydra:/etc/config/hydra
    command: serve -c /etc/config/hydra/hydra.yml all --dev
    depends_on:
      hydra-migrate:
        condition: service_completed_successfully
    networks:
      - ory-net
      - hydranet



  # --- Keto ---
  keto-migrate:
    image: oryd/keto:${KETO_VERSION:-v25.4.0}
    environment:
      - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB}?sslmode=disable&max_conns=20
    volumes:
      - ./docker/ory/keto:/etc/config/keto
    command: migrate up -c /etc/config/keto/keto.yml --yes
    depends_on:
      postgres_ory:
        condition: service_healthy
    networks:
      - ory-net

  keto:
    image: oryd/keto:${KETO_VERSION:-v25.4.0}
    container_name: ory_keto
    environment:
      - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB}?sslmode=disable&max_conns=20
    volumes:
      - ./docker/ory/keto:/etc/config/keto
    command: serve -c /etc/config/keto/keto.yml
    depends_on:
      keto-migrate:
        condition: service_completed_successfully
    networks:
      - ory-net

  # --- Oathkeeper ---
  oathkeeper:
    image: oryd/oathkeeper:${OATHKEEPER_VERSION:-v25.4.0}
    container_name: ory_oathkeeper
    user: "${OATHKEEPER_UID:-1001}:${OATHKEEPER_GID:-1001}"
    ports:
      - "4457:4455" # Proxy
    environment:
      - LOG_LEVEL=${OATHKEEPER_LOG_LEVEL:info}
      - APP_ENV=${APP_ENV:-development}
    volumes:
      - ./docker/ory/oathkeeper:/etc/config/oathkeeper
      - ./docker/ory/oathkeeper/logs:/var/log/oathkeeper
    entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"]
    networks:
      - ory-net

  ory_clickhouse:
    image: clickhouse/clickhouse-server:latest
    container_name: ory_clickhouse
    environment:
      - CLICKHOUSE_USER=${ORY_CLICKHOUSE_USER:-ory}
      - CLICKHOUSE_PASSWORD=${ORY_CLICKHOUSE_PASSWORD:-orypass}
    volumes:
      - ory_clickhouse_data:/var/lib/clickhouse
      - ./docker/ory/clickhouse:/docker-entrypoint-initdb.d
    networks:
      - ory-net

  ory_vector:
    image: timberio/vector:0.36.0-alpine
    container_name: ory_vector
    volumes:
      - ./docker/ory/vector:/etc/vector
      - ./docker/ory/oathkeeper/logs:/var/log/oathkeeper
    command: ["-c", "/etc/vector/vector.toml"]
    depends_on:
      - oathkeeper
      - ory_clickhouse
    networks:
      - ory-net

  # --- 초기화 & 헬스체크 ---
  ory_stack_check:
    image: alpine:latest
    container_name: ory_stack_check
    command: >
      /bin/sh -c "
        apk add --no-cache curl;
        echo 'Wait for services...';
        until curl -s http://kratos:4433/health/ready; do sleep 1; done;
        until curl -s http://hydra:4444/health/ready; do sleep 1; done;
        until curl -s http://keto:4466/health/ready; do sleep 1; done;
        echo 'Ory Stack is fully operational!';"
    depends_on:
      - kratos
      - hydra
      - keto
    networks:
      - ory-net

  # 기본 RP (Admin Front 등) 자동 등록 컨테이너
  init-rp:
    image: oryd/hydra:${HYDRA_VERSION:-v25.4.0}
    environment:
      - HYDRA_ADMIN_URL=http://hydra:4445
    command: >
      /bin/sh -c "
      hydra clients create
      --endpoint http://hydra:4445
      --id adminfront
      --secret admin-secret
      --grant-types authorization_code,refresh_token
      --response-types code
      --scope openid,offline_access,profile,email
      --callbacks http://localhost:5000/callback;
      hydra clients create
      --endpoint http://hydra:4445
      --id devfront
      --grant-types authorization_code,refresh_token
      --response-types code
      --scope openid,offline_access,profile,email
      --token-endpoint-auth-method none
      --callbacks http://localhost:5174/callback;
      "
    depends_on:
      ory_stack_check:
        condition: service_completed_successfully
    networks:
      - hydranet

volumes:
    ory_postgres_data:
    ory_clickhouse_data:

networks:
  ory-net:
    external: true
    name: ory-net
  hydranet:
    external: true
    name: hydranet
  kratosnet:
    external: true
    name: kratosnet
