From 20590b67d9b5b6a11b3d609a50fafe4565544882 Mon Sep 17 00:00:00 2001 From: chan Date: Fri, 6 Feb 2026 16:24:04 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=ED=8F=AC=EC=9A=A9=20=EB=8F=84?= =?UTF-8?q?=EC=BB=A4=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/compose.infra.yaml | 82 ++++++++++++ docker/compose.ory.yaml | 255 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 337 insertions(+) create mode 100644 docker/compose.infra.yaml create mode 100644 docker/compose.ory.yaml diff --git a/docker/compose.infra.yaml b/docker/compose.infra.yaml new file mode 100644 index 00000000..368b8911 --- /dev/null +++ b/docker/compose.infra.yaml @@ -0,0 +1,82 @@ +services: + postgres: + image: postgres:17-alpine + container_name: baron_postgres + environment: + POSTGRES_USER: ${DB_USER:-baron} + POSTGRES_PASSWORD: ${DB_PASSWORD:-password} + POSTGRES_DB: ${DB_NAME:-baron_sso} + ports: + - "${DB_PORT:-5432}:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + - ./docker/init-metadata:/docker-entrypoint-initdb.d + networks: + - baron_net + healthcheck: + test: + [ + "CMD-SHELL", + "pg_isready -U ${DB_USER:-baron} -d ${DB_NAME:-baron_sso}", + ] + interval: 5s + timeout: 5s + retries: 5 + restart: always + + clickhouse: + image: clickhouse/clickhouse-server:latest + container_name: baron_clickhouse + restart: always + volumes: + - clickhouse_data:/var/lib/clickhouse + environment: + CLICKHOUSE_USER: ${CLICKHOUSE_USER:-baron} + CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-password} + networks: + - baron_net + + redis: + image: redis:7-alpine + container_name: baron_redis + restart: always + command: redis-server --port 6389 + ports: + - "6389:6389" + volumes: + - redis_data:/data + networks: + - baron_net + + gateway: + build: + context: ./gateway + dockerfile: Dockerfile + container_name: baron_gateway + restart: always + ports: + - "${USERFRONT_PORT:-5000}:5000" + networks: + - baron_net + - public_net + healthcheck: + test: ["CMD", "wget", "-qO-", "http://127.0.0.1:5000/"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 10s + +volumes: + postgres_data: + clickhouse_data: + redis_data: + +networks: + baron_net: + name: baron_net + external: true + driver: bridge + public_net: + name: public_net + external: true + diff --git a/docker/compose.ory.yaml b/docker/compose.ory.yaml new file mode 100644 index 00000000..5e9d5f9d --- /dev/null +++ b/docker/compose.ory.yaml @@ -0,0 +1,255 @@ +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:-ory_kratos}?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:5000} + - KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=["${KRATOS_UI_URL:-http://localhost:5000}","${USERFRONT_URL:-http://localhost:5000}"] + - KRATOS_SELFSERVICE_FLOWS_ERROR_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/error + - KRATOS_SELFSERVICE_FLOWS_SETTINGS_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/error?error=settings_disabled + - KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/recovery + - KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/verification + - KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/login + - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/registration + - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL:-http://localhost:5000}/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 + environment: + - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KRATOS_DB:-ory_kratos}?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:5000} + - KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=["${KRATOS_UI_URL:-http://localhost:5000}","${USERFRONT_URL:-http://localhost:5000}"] + - KRATOS_SELFSERVICE_FLOWS_ERROR_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/error + - KRATOS_SELFSERVICE_FLOWS_SETTINGS_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/error?error=settings_disabled + - KRATOS_SELFSERVICE_FLOWS_RECOVERY_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/recovery + - KRATOS_SELFSERVICE_FLOWS_VERIFICATION_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/verification + - KRATOS_SELFSERVICE_FLOWS_LOGIN_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/login + - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL:-http://localhost:5000}/registration + - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL:-http://localhost:5000}/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 + + # --- 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:-ory_hydra}?sslmode=disable&max_conns=20 + command: migrate sql up -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:-ory_hydra}?sslmode=disable&max_conns=20 + - URLS_SELF_ISSUER=${USERFRONT_URL:-http://localhost:5000}/oidc + - URLS_LOGIN=${USERFRONT_URL:-http://localhost:5000}/login + - URLS_CONSENT=${USERFRONT_URL:-http://localhost:5000}/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:-ory_keto}?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:-ory_keto}?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: + - APP_ENV=${APP_ENV:-development} + - LOG_LEVEL=debug + - OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect} + - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret} + volumes: + - ./docker/ory/oathkeeper:/etc/config/oathkeeper + - ./docker/ory/oathkeeper/logs:/var/log/oathkeeper + entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"] + networks: + - ory-net + - public_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 + - OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect} + - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret} + command: | + 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 \ + --response-types code \ + --callbacks http://localhost:5174/callback; + + hydra clients create \ + --endpoint http://hydra:4445 \ + --id "$OATHKEEPER_INTROSPECT_CLIENT_ID" \ + --secret "$OATHKEEPER_INTROSPECT_CLIENT_SECRET" \ + --grant-types client_credentials \ + --response-types token \ + --scope openid,offline_access,profile,email; + 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 + public_net: + external: true + name: public_net