1
0
forked from baron/baron-sso

go 버전업 && ory 설정파일들 자동 생성 스크립트 추가

This commit is contained in:
2026-05-07 11:01:25 +09:00
parent 45a14163bf
commit 2cba9c9c1f
25 changed files with 504 additions and 144 deletions

View File

@@ -163,8 +163,9 @@ jobs:
done done
# [중요] 설정 파일 권한 문제 해결 (Ory 이미지는 root가 아닌 사용자로 실행됨) # Ory 컨테이너가 직접 읽는 설정은 env 기반으로 완성한 뒤 mount합니다.
chmod -R 777 docker/ory || true bash scripts/render_ory_config.sh
chmod -R 777 config/.generated/ory || true
cp docker/staging_pull_compose.template.yaml staging_pull_compose.yaml cp docker/staging_pull_compose.template.yaml staging_pull_compose.yaml

1
.gitignore vendored
View File

@@ -8,6 +8,7 @@
.codex/ .codex/
.serena/ .serena/
.generated/ .generated/
config/.generated/
*.swp *.swp
*.log *.log
*.out *.out

View File

@@ -10,7 +10,7 @@ endif
COMPOSE_INFRA := compose.infra.yaml COMPOSE_INFRA := compose.infra.yaml
COMPOSE_ORY := compose.ory.yaml COMPOSE_ORY := compose.ory.yaml
COMPOSE_APP := docker-compose.yaml COMPOSE_APP := docker-compose.yaml
AUTH_CONFIG_ENV := .generated/auth-config.env AUTH_CONFIG_ENV := config/.generated/auth-config.env
DEV_SERVICES ?= backend adminfront devfront orgfront userfront DEV_SERVICES ?= backend adminfront devfront orgfront userfront
DEV_NETWORKS := baron_net ory-net hydranet kratosnet public_net DEV_NETWORKS := baron_net ory-net hydranet kratosnet public_net
INFRA_CONTAINERS := baron_postgres baron_clickhouse baron_redis baron_gateway INFRA_CONTAINERS := baron_postgres baron_clickhouse baron_redis baron_gateway
@@ -29,12 +29,12 @@ ifneq (,$(wildcard ./.env))
COMPOSE_DROP_ENV_ARGS += --env-file .env COMPOSE_DROP_ENV_ARGS += --env-file .env
endif endif
.PHONY: build-auth-config validate-auth-config verify-auth-config up up-all up-infra up-ory up-app up-backend ensure-networks ensure-infra ensure-ory up-dev up-front-dev dev down drop down-app down-backend down-infra down-ory check-infra ps logs-infra logs-ory logs-app .PHONY: build-auth-config validate-auth-config verify-auth-config render-ory-config up up-all up-infra up-ory up-app up-backend ensure-networks ensure-infra ensure-ory up-dev up-front-dev dev down drop down-app down-backend down-infra down-ory check-infra ps logs-infra logs-ory logs-app
# --- 인증 설정 빌드/검증 --- # --- 인증 설정 빌드/검증 ---
build-auth-config: build-auth-config:
@echo "Building auth config..." @echo "Building auth config..."
@mkdir -p .generated @mkdir -p config/.generated
@bash scripts/auth_config.sh build @bash scripts/auth_config.sh build
validate-auth-config: build-auth-config validate-auth-config: build-auth-config
@@ -45,30 +45,34 @@ verify-auth-config: validate-auth-config
@echo "Verifying auth config wiring..." @echo "Verifying auth config wiring..."
@bash scripts/auth_config.sh verify @bash scripts/auth_config.sh verify
render-ory-config: validate-auth-config
@echo "Rendering Ory config..."
@bash scripts/render_ory_config.sh
# --- 기본 실행 --- # --- 기본 실행 ---
# 주의: --remove-orphan 사용 금지 (다른 스택이 orphan으로 판단되어 종료될 수 있음) # 주의: --remove-orphan 사용 금지 (다른 스택이 orphan으로 판단되어 종료될 수 있음)
up: up-all up: up-all
up-all: ensure-networks validate-auth-config up-all: ensure-networks render-ory-config
@echo "Starting ALL stacks (infra + ory + app)..." @echo "Starting ALL stacks (infra + ory + app)..."
docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_INFRA) -f $(COMPOSE_ORY) -f $(COMPOSE_APP) up -d docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_INFRA) -f $(COMPOSE_ORY) -f $(COMPOSE_APP) up --build -d
# --- 개별 스택 실행 --- # --- 개별 스택 실행 ---
up-infra: ensure-networks up-infra: ensure-networks
@echo "Starting Infra stack (postgres/clickhouse/redis)..." @echo "Starting Infra stack (postgres/clickhouse/redis)..."
docker compose -f $(COMPOSE_INFRA) up -d docker compose -f $(COMPOSE_INFRA) up -d
up-ory: ensure-networks validate-auth-config up-ory: ensure-networks render-ory-config
@echo "Starting Ory stack (kratos/hydra/keto/oathkeeper)..." @echo "Starting Ory stack (kratos/hydra/keto/oathkeeper)..."
docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_ORY) up -d docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_ORY) up -d
up-app: ensure-networks validate-auth-config up-app: ensure-networks render-ory-config
@echo "Starting App stack (backend/userfront/adminfront/devfront/orgfront)..." @echo "Starting App stack (backend/userfront/adminfront/devfront/orgfront)..."
docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up -d docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up --build -d
up-backend: ensure-networks validate-auth-config up-backend: ensure-networks render-ory-config
@echo "Starting Backend only..." @echo "Starting Backend only..."
docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up -d backend docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up --build -d backend
ensure-networks: ensure-networks:
@echo "Ensuring Docker networks..." @echo "Ensuring Docker networks..."
@@ -97,7 +101,7 @@ ensure-infra: ensure-networks
echo "Infra stack is already running."; \ echo "Infra stack is already running."; \
fi fi
ensure-ory: ensure-networks validate-auth-config ensure-ory: ensure-networks render-ory-config
@echo "Ensuring Ory stack..." @echo "Ensuring Ory stack..."
@missing=0; \ @missing=0; \
for container in $(ORY_CONTAINERS); do \ for container in $(ORY_CONTAINERS); do \
@@ -121,7 +125,7 @@ up-front-dev: up-infra up-ory up-backend
dev: up-dev dev: up-dev
@echo "Starting development app containers in foreground attach mode..." @echo "Starting development app containers in foreground attach mode..."
docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up $(DEV_SERVICES) docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up --build $(DEV_SERVICES)
# --- 종료 (Down) --- # --- 종료 (Down) ---
down: down:

View File

@@ -66,7 +66,7 @@ flowchart
``` ```
### 1. Backend (Go Fiber) ### 1. Backend (Go Fiber)
- **Language**: Go 1.25+ - **Language**: Go 1.26.2+
- **Framework**: Fiber v2.25+ - **Framework**: Fiber v2.25+
- **Database**: - **Database**:
- **ClickHouse**: 감사 로그 (고성능 데이터 수집) - **ClickHouse**: 감사 로그 (고성능 데이터 수집)
@@ -436,7 +436,7 @@ USERFRONT_URL=https://sso.example.com
```bash ```bash
make validate-auth-config make validate-auth-config
``` ```
위 검증은 callback/allowed_return_urls/게이트웨이 매핑 규칙을 점검하고 `.generated/auth-config.env`를 생성합니다. 위 검증은 callback/allowed_return_urls/게이트웨이 매핑 규칙을 점검하고 `config/.generated/auth-config.env`를 생성합니다.
### 전체 스택 실행 (Running the Stack) ### 전체 스택 실행 (Running the Stack)
@@ -478,7 +478,7 @@ make validate-auth-config
make verify-auth-config make verify-auth-config
``` ```
- 생성 파일: `.generated/auth-config.env` (compose 실행 시 자동 주입) - 생성 파일: `config/.generated/auth-config.env` (compose 실행 시 자동 주입)
- 게이트웨이 경유 환경은 URL 문자열 완전일치 대신 매핑 유효성(`direct_match` / `mapped_match`) 기준으로 검증합니다. - 게이트웨이 경유 환경은 URL 문자열 완전일치 대신 매핑 유효성(`direct_match` / `mapped_match`) 기준으로 검증합니다.
- 관련 정책 문서: `docs/oidc_redirect_mapping_validation_policy.md` - 관련 정책 문서: `docs/oidc_redirect_mapping_validation_policy.md`
@@ -493,8 +493,8 @@ make up-app
직접 Compose를 사용하려면 다음처럼 env 파일을 함께 주입하세요. 직접 Compose를 사용하려면 다음처럼 env 파일을 함께 주입하세요.
```bash ```bash
docker compose --env-file .env --env-file .generated/auth-config.env -f compose.infra.yaml -f compose.ory.yaml up -d docker compose --env-file .env --env-file config/.generated/auth-config.env -f compose.infra.yaml -f compose.ory.yaml up -d
docker compose --env-file .env --env-file .generated/auth-config.env -f docker-compose.yaml up -d docker compose --env-file .env --env-file config/.generated/auth-config.env -f docker-compose.yaml up -d
``` ```
- **gateway (UserFront 프록시)**: http://localhost:5000 접속 - **gateway (UserFront 프록시)**: http://localhost:5000 접속

View File

@@ -14,7 +14,7 @@ It leverages **Descope** for secure, passwordless authentication (Enchanted Link
- Descope SDK Integration (Enchanted Link, Magic Link) - Descope SDK Integration (Enchanted Link, Magic Link)
### 2. Backend (Go Fiber) ### 2. Backend (Go Fiber)
- **Language**: Go 1.25+ - **Language**: Go 1.26.2+
- **Framework**: Fiber v2.25+ - **Framework**: Fiber v2.25+
- **Database**: - **Database**:
- **ClickHouse**: Audit Logs (High performance ingestion) - **ClickHouse**: Audit Logs (High performance ingestion)

View File

@@ -1,4 +1,4 @@
FROM golang:1.25-alpine FROM golang:1.26.2-alpine
WORKDIR /app WORKDIR /app

View File

@@ -1,6 +1,6 @@
module baron-sso-backend module baron-sso-backend
go 1.25.4 go 1.26.2
require ( require (
github.com/ClickHouse/clickhouse-go/v2 v2.42.0 github.com/ClickHouse/clickhouse-go/v2 v2.42.0

View File

@@ -38,7 +38,7 @@ services:
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
volumes: volumes:
- ./docker/ory/kratos:/etc/config/kratos - ./config/.generated/ory/kratos:/etc/config/kratos
command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes
depends_on: depends_on:
postgres_ory: postgres_ory:
@@ -64,7 +64,7 @@ services:
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
volumes: volumes:
- ./docker/ory/kratos:/etc/config/kratos - ./config/.generated/ory/kratos:/etc/config/kratos
command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
depends_on: depends_on:
kratos-migrate: kratos-migrate:
@@ -96,7 +96,7 @@ services:
- URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error} - URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error}
- SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD} - SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD}
volumes: volumes:
- ./docker/ory/hydra:/etc/config/hydra - ./config/.generated/ory/hydra:/etc/config/hydra
command: serve -c /etc/config/hydra/hydra.yml all --dev command: serve -c /etc/config/hydra/hydra.yml all --dev
depends_on: depends_on:
hydra-migrate: hydra-migrate:
@@ -111,7 +111,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./docker/ory/keto:/etc/config/keto - ./config/.generated/ory/keto:/etc/config/keto
command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"] command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"]
depends_on: depends_on:
postgres_ory: postgres_ory:
@@ -125,7 +125,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./docker/ory/keto:/etc/config/keto - ./config/.generated/ory/keto:/etc/config/keto
command: serve -c /etc/config/keto/keto.yml command: serve -c /etc/config/keto/keto.yml
depends_on: depends_on:
keto-migrate: keto-migrate:
@@ -159,7 +159,7 @@ services:
- OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect} - OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}
- OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret} - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}
volumes: volumes:
- ./docker/ory/oathkeeper:/etc/config/oathkeeper - ./config/.generated/ory/oathkeeper:/etc/config/oathkeeper
- oathkeeper_logs:/var/log/oathkeeper - oathkeeper_logs:/var/log/oathkeeper
entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"] entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"]
depends_on: depends_on:
@@ -205,9 +205,27 @@ services:
/bin/sh -c " /bin/sh -c "
apk add --no-cache curl; apk add --no-cache curl;
echo 'Wait for services...'; echo 'Wait for services...';
until curl -s http://kratos:4433/health/ready; do sleep 1; done; check_ready() {
until curl -s http://hydra:4444/health/ready; do sleep 1; done; name=\"$$1\";
until curl -s http://keto:4466/health/ready; do sleep 1; done; url=\"$$2\";
max=\"$${ORY_STACK_CHECK_MAX_ATTEMPTS:-60}\";
i=1;
while [ \"$$i\" -le \"$$max\" ]; do
if curl --connect-timeout 2 --max-time 3 -fsS \"$$url\" >/dev/null; then
echo \"Ory service ready: $$name\";
return 0;
fi;
echo \"Waiting for Ory service: $$name ($$i/$$max)\";
i=$$((i + 1));
sleep 1;
done;
echo \"ERROR: Ory service not ready: $$name after $$max attempts ($$url)\" >&2;
echo \"ERROR: Check service logs: docker logs ory_$$name\" >&2;
return 1;
};
check_ready kratos http://kratos:4433/health/ready || exit 1;
check_ready hydra http://hydra:4444/health/ready || exit 1;
check_ready keto http://keto:4466/health/ready || exit 1;
echo 'Ory Stack is fully operational!';" echo 'Ory Stack is fully operational!';"
depends_on: depends_on:
- kratos - kratos

View File

@@ -18,11 +18,12 @@ echo "🚀 Creating instance: ${INSTANCE_NAME} (Port Prefix: ${PORT_PREFIX}xxx)"
# 1. 폴더 구조 생성 # 1. 폴더 구조 생성
mkdir -p "${TARGET_DIR}/gateway" mkdir -p "${TARGET_DIR}/gateway"
mkdir -p "${TARGET_DIR}/config/.generated"
mkdir -p "${TARGET_DIR}/ory/init-db" mkdir -p "${TARGET_DIR}/ory/init-db"
mkdir -p "${TARGET_DIR}/ory/kratos" mkdir -p "${TARGET_DIR}/ory/templates/kratos"
mkdir -p "${TARGET_DIR}/ory/hydra" mkdir -p "${TARGET_DIR}/ory/templates/hydra"
mkdir -p "${TARGET_DIR}/ory/keto" mkdir -p "${TARGET_DIR}/ory/templates/keto"
mkdir -p "${TARGET_DIR}/ory/oathkeeper" mkdir -p "${TARGET_DIR}/ory/templates/oathkeeper"
mkdir -p "${TARGET_DIR}/userfront" mkdir -p "${TARGET_DIR}/userfront"
mkdir -p "${TARGET_DIR}/adminfront" mkdir -p "${TARGET_DIR}/adminfront"
mkdir -p "${TARGET_DIR}/devfront" mkdir -p "${TARGET_DIR}/devfront"
@@ -47,13 +48,15 @@ cp "${BASE_DIR}/templates/docker-compose.yaml" "${TARGET_DIR}/"
sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" "${BASE_DIR}/templates/gateway/nginx.conf" > "${TARGET_DIR}/gateway/nginx.conf" sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" "${BASE_DIR}/templates/gateway/nginx.conf" > "${TARGET_DIR}/gateway/nginx.conf"
sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" "${BASE_DIR}/templates/userfront/nginx.conf" > "${TARGET_DIR}/userfront/nginx.conf" sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" "${BASE_DIR}/templates/userfront/nginx.conf" > "${TARGET_DIR}/userfront/nginx.conf"
# Oathkeeper Rules # Oathkeeper Rules template
sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" "${BASE_DIR}/templates/ory/oathkeeper/rules.json" > "${TARGET_DIR}/ory/oathkeeper/rules.json" sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" "${BASE_DIR}/templates/ory/oathkeeper/rules.json" > "${TARGET_DIR}/ory/templates/oathkeeper/rules.json"
cp "${TARGET_DIR}/ory/oathkeeper/rules.json" "${TARGET_DIR}/ory/oathkeeper/rules.active.json" cp "${TARGET_DIR}/ory/templates/oathkeeper/rules.json" "${TARGET_DIR}/ory/templates/oathkeeper/rules.stage.json"
cp "${TARGET_DIR}/ory/templates/oathkeeper/rules.json" "${TARGET_DIR}/ory/templates/oathkeeper/rules.prod.json"
cp "${TARGET_DIR}/ory/templates/oathkeeper/rules.json" "${TARGET_DIR}/ory/templates/oathkeeper/rules.active.json"
# Kratos Config # Kratos Config template
sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g; s/{{USERFRONT_PORT}}/${USERFRONT_PORT}/g" \ sed "s/{{BACKEND_PORT}}/${BACKEND_PORT}/g; s/{{USERFRONT_PORT}}/${USERFRONT_PORT}/g" \
"${BASE_DIR}/templates/ory/kratos/kratos.yml" > "${TARGET_DIR}/ory/kratos/kratos.yml" "${BASE_DIR}/templates/ory/kratos/kratos.yml.template" > "${TARGET_DIR}/ory/templates/kratos/kratos.yml.template"
# Vite Configs # Vite Configs
sed "s/{{ADMINFRONT_DOMAIN}}/${ADMINFRONT_DOMAIN}/g; s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" \ sed "s/{{ADMINFRONT_DOMAIN}}/${ADMINFRONT_DOMAIN}/g; s/{{BACKEND_PORT}}/${BACKEND_PORT}/g" \
@@ -71,12 +74,18 @@ sed "s/{{USERFRONT_PORT}}/${USERFRONT_PORT}/g; s/{{CLIENT_ID}}/devfront/g" \
sed "s/{{USERFRONT_PORT}}/${USERFRONT_PORT}/g" \ sed "s/{{USERFRONT_PORT}}/${USERFRONT_PORT}/g" \
"${BASE_DIR}/templates/orgfront/auth.ts" > "${TARGET_DIR}/orgfront/auth.ts" "${BASE_DIR}/templates/orgfront/auth.ts" > "${TARGET_DIR}/orgfront/auth.ts"
# 5. Ory 정적 설정 복사 # 5. Ory template 복사 및 완성 config 렌더링
if [ -d "${BASE_DIR}/../docker/ory/init-db" ]; then cp -n "${BASE_DIR}/../docker/ory/init-db/"* "${TARGET_DIR}/ory/init-db/" 2>/dev/null || true; fi if [ -d "${BASE_DIR}/../docker/ory/init-db" ]; then cp -n "${BASE_DIR}/../docker/ory/init-db/"* "${TARGET_DIR}/ory/init-db/" 2>/dev/null || true; fi
if [ -d "${BASE_DIR}/../docker/ory/kratos" ]; then cp -n "${BASE_DIR}/../docker/ory/kratos/"* "${TARGET_DIR}/ory/kratos/" 2>/dev/null || true; fi if [ -d "${BASE_DIR}/../docker/ory/kratos" ]; then cp -n "${BASE_DIR}/../docker/ory/kratos/"* "${TARGET_DIR}/ory/templates/kratos/" 2>/dev/null || true; fi
if [ -d "${BASE_DIR}/../docker/ory/hydra" ]; then cp -n "${BASE_DIR}/../docker/ory/hydra/"* "${TARGET_DIR}/ory/hydra/" 2>/dev/null || true; fi if [ -d "${BASE_DIR}/../docker/ory/kratos/courier-templates" ]; then cp -a "${BASE_DIR}/../docker/ory/kratos/courier-templates" "${TARGET_DIR}/ory/templates/kratos/" 2>/dev/null || true; fi
if [ -d "${BASE_DIR}/../docker/ory/keto" ]; then cp -n "${BASE_DIR}/../docker/ory/keto/"* "${TARGET_DIR}/ory/keto/" 2>/dev/null || true; fi if [ -d "${BASE_DIR}/../docker/ory/hydra" ]; then cp -n "${BASE_DIR}/../docker/ory/hydra/"* "${TARGET_DIR}/ory/templates/hydra/" 2>/dev/null || true; fi
if [ -d "${BASE_DIR}/../docker/ory/oathkeeper" ]; then cp -n "${BASE_DIR}/../docker/ory/oathkeeper/"* "${TARGET_DIR}/ory/oathkeeper/" 2>/dev/null || true; fi if [ -d "${BASE_DIR}/../docker/ory/keto" ]; then cp -n "${BASE_DIR}/../docker/ory/keto/"* "${TARGET_DIR}/ory/templates/keto/" 2>/dev/null || true; fi
if [ -d "${BASE_DIR}/../docker/ory/oathkeeper" ]; then cp -n "${BASE_DIR}/../docker/ory/oathkeeper/"* "${TARGET_DIR}/ory/templates/oathkeeper/" 2>/dev/null || true; fi
ORY_CONFIG_ENV_FILES="${TARGET_DIR}/.env" \
ORY_CONFIG_TEMPLATE_ROOT="${TARGET_DIR}/ory/templates" \
ORY_CONFIG_OUTPUT_DIR="${TARGET_DIR}/config/.generated/ory" \
bash "${BASE_DIR}/../scripts/render_ory_config.sh"
# 6. 마무리 # 6. 마무리
chmod +x "${TARGET_DIR}/.env" chmod +x "${TARGET_DIR}/.env"

View File

@@ -69,7 +69,7 @@ services:
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
volumes: volumes:
- ./ory/kratos:/etc/config/kratos:ro - ./config/.generated/ory/kratos:/etc/config/kratos:ro
command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes
networks: [app_net] networks: [app_net]
depends_on: depends_on:
@@ -94,7 +94,7 @@ services:
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
volumes: volumes:
- ./ory/kratos:/etc/config/kratos:ro - ./config/.generated/ory/kratos:/etc/config/kratos:ro
command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
networks: [app_net] networks: [app_net]
depends_on: depends_on:
@@ -122,7 +122,7 @@ services:
- URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error} - URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error}
- SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD} - SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD}
volumes: volumes:
- ./ory/hydra:/etc/config/hydra:ro - ./config/.generated/ory/hydra:/etc/config/hydra:ro
command: serve -c /etc/config/hydra/hydra.yml all --dev command: serve -c /etc/config/hydra/hydra.yml all --dev
networks: [app_net] networks: [app_net]
depends_on: depends_on:
@@ -134,7 +134,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER:-ory}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER:-ory}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./ory/keto:/etc/config/keto:ro - ./config/.generated/ory/keto:/etc/config/keto:ro
command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"] command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"]
networks: [app_net] networks: [app_net]
depends_on: depends_on:
@@ -147,7 +147,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER:-ory}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER:-ory}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./ory/keto:/etc/config/keto:ro - ./config/.generated/ory/keto:/etc/config/keto:ro
command: serve -c /etc/config/keto/keto.yml command: serve -c /etc/config/keto/keto.yml
networks: [app_net] networks: [app_net]
depends_on: depends_on:
@@ -173,7 +173,7 @@ services:
- OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect} - OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}
- OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret} - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}
volumes: volumes:
- ./ory/oathkeeper:/etc/config/oathkeeper:ro - ./config/.generated/ory/oathkeeper:/etc/config/oathkeeper:ro
- oathkeeper_logs:/var/log/oathkeeper - oathkeeper_logs:/var/log/oathkeeper
entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"] entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"]
networks: [app_net] networks: [app_net]
@@ -189,9 +189,27 @@ services:
/bin/sh -c " /bin/sh -c "
apk add --no-cache curl; apk add --no-cache curl;
echo 'Wait for Ory services...'; echo 'Wait for Ory services...';
until curl -s http://kratos:4433/health/ready; do sleep 1; done; check_ready() {
until curl -s http://hydra:4444/health/ready; do sleep 1; done; name=\"$$1\";
until curl -s http://keto:4466/health/ready; do sleep 1; done; url=\"$$2\";
max=\"$${ORY_STACK_CHECK_MAX_ATTEMPTS:-60}\";
i=1;
while [ \"$$i\" -le \"$$max\" ]; do
if curl --connect-timeout 2 --max-time 3 -fsS \"$$url\" >/dev/null; then
echo \"Ory service ready: $$name\";
return 0;
fi;
echo \"Waiting for Ory service: $$name ($$i/$$max)\";
i=$$((i + 1));
sleep 1;
done;
echo \"ERROR: Ory service not ready: $$name after $$max attempts ($$url)\" >&2;
echo \"ERROR: Check service logs: docker logs $${COMPOSE_PROJECT_NAME}_$$name\" >&2;
return 1;
};
check_ready kratos http://kratos:4433/health/ready || exit 1;
check_ready hydra http://hydra:4444/health/ready || exit 1;
check_ready keto http://keto:4466/health/ready || exit 1;
echo 'Ory stack is ready.';" echo 'Ory stack is ready.';"
depends_on: depends_on:
- kratos - kratos

View File

@@ -1,20 +1,17 @@
version: v26.2.0 version: v26.2.0
dsn: ${DSN} dsn: ${KRATOS_DSN}
serve: serve:
public: public:
base_url: ${KRATOS_BROWSER_URL} base_url: http://localhost:4433/
cors: cors:
enabled: true enabled: true
allowed_origins: allowed_origins:
- http://backend:{{BACKEND_PORT}} - http://backend:{{BACKEND_PORT}}
- ${USERFRONT_URL} - http://localhost:{{USERFRONT_PORT}}
- ${ADMINFRONT_URL}
- ${DEVFRONT_URL}
- ${ORGFRONT_URL}
admin: admin:
base_url: ${KRATOS_ADMIN_URL} base_url: http://localhost:4434/
session: session:
cookie: cookie:
@@ -23,22 +20,17 @@ session:
path: / path: /
selfservice: selfservice:
default_browser_return_url: ${KRATOS_UI_URL} default_browser_return_url: http://localhost:{{USERFRONT_PORT}}/
allowed_return_urls: allowed_return_urls:
- ${KRATOS_UI_URL} - http://localhost:{{USERFRONT_PORT}}
- ${KRATOS_UI_URL}/ - http://localhost:{{USERFRONT_PORT}}/
- ${USERFRONT_URL} - http://localhost:{{USERFRONT_PORT}}/ko
- ${USERFRONT_URL}/ - http://localhost:{{USERFRONT_PORT}}/ko/
- ${USERFRONT_URL}/ko - http://localhost:{{USERFRONT_PORT}}/en
- ${USERFRONT_URL}/ko/ - http://localhost:{{USERFRONT_PORT}}/en/
- ${USERFRONT_URL}/en - http://localhost:{{USERFRONT_PORT}}/auth/callback
- ${USERFRONT_URL}/en/ - http://localhost:{{USERFRONT_PORT}}/ko/auth/callback
- ${USERFRONT_URL}/auth/callback - http://localhost:{{USERFRONT_PORT}}/en/auth/callback
- ${USERFRONT_URL}/ko/auth/callback
- ${USERFRONT_URL}/en/auth/callback
- ${ADMINFRONT_URL}/auth/callback
- ${DEVFRONT_URL}/auth/callback
- ${ORGFRONT_URL}/auth/callback
methods: methods:
password: password:
@@ -51,24 +43,24 @@ selfservice:
flows: flows:
error: error:
ui_url: ${KRATOS_UI_URL}/error ui_url: http://localhost:{{USERFRONT_PORT}}/error
settings: settings:
ui_url: ${KRATOS_UI_URL}/error?error=settings_disabled ui_url: http://localhost:{{USERFRONT_PORT}}/error?error=settings_disabled
privileged_session_max_age: 15m privileged_session_max_age: 15m
recovery: recovery:
ui_url: ${KRATOS_UI_URL}/recovery ui_url: http://localhost:{{USERFRONT_PORT}}/recovery
use: code use: code
verification: verification:
ui_url: ${KRATOS_UI_URL}/verification ui_url: http://localhost:{{USERFRONT_PORT}}/verification
use: code use: code
logout: logout:
after: after:
default_browser_return_url: ${KRATOS_UI_URL}/login default_browser_return_url: http://localhost:{{USERFRONT_PORT}}/login
login: login:
ui_url: ${KRATOS_UI_URL}/login ui_url: http://localhost:{{USERFRONT_PORT}}/login
lifespan: 10m lifespan: 10m
registration: registration:
ui_url: ${KRATOS_UI_URL}/registration ui_url: http://localhost:{{USERFRONT_PORT}}/registration
lifespan: 10m lifespan: 10m
log: log:

View File

@@ -30,7 +30,7 @@ services:
- KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL} - KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}
- KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=${KRATOS_ALLOWED_RETURN_URLS_JSON:-["${KRATOS_UI_URL}","${USERFRONT_URL}"]} - KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=${KRATOS_ALLOWED_RETURN_URLS_JSON:-["${KRATOS_UI_URL}","${USERFRONT_URL}"]}
volumes: volumes:
- ./docker/ory/kratos:/etc/config/kratos - ../config/.generated/ory/kratos:/etc/config/kratos
command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes
depends_on: depends_on:
postgres_ory: postgres_ory:
@@ -49,7 +49,7 @@ services:
- KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL} - KRATOS_SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}
- KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=${KRATOS_ALLOWED_RETURN_URLS_JSON:-["${KRATOS_UI_URL}","${USERFRONT_URL}"]} - KRATOS_SELFSERVICE_ALLOWED_RETURN_URLS=${KRATOS_ALLOWED_RETURN_URLS_JSON:-["${KRATOS_UI_URL}","${USERFRONT_URL}"]}
volumes: volumes:
- ./docker/ory/kratos:/etc/config/kratos - ../config/.generated/ory/kratos:/etc/config/kratos
command: serve -c /etc/config/kratos/kratos.yml command: serve -c /etc/config/kratos/kratos.yml
depends_on: depends_on:
kratos-migrate: kratos-migrate:
@@ -80,7 +80,7 @@ services:
- URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error} - URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error}
- SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD} - SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD}
volumes: volumes:
- ./docker/ory/hydra:/etc/config/hydra - ../config/.generated/ory/hydra:/etc/config/hydra
command: serve -c /etc/config/hydra/hydra.yml all --dev command: serve -c /etc/config/hydra/hydra.yml all --dev
depends_on: depends_on:
hydra-migrate: hydra-migrate:
@@ -94,7 +94,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./docker/ory/keto:/etc/config/keto - ../config/.generated/ory/keto:/etc/config/keto
command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"] command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"]
depends_on: depends_on:
postgres_ory: postgres_ory:
@@ -108,7 +108,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./docker/ory/keto:/etc/config/keto - ../config/.generated/ory/keto:/etc/config/keto
command: serve -c /etc/config/keto/keto.yml command: serve -c /etc/config/keto/keto.yml
depends_on: depends_on:
keto-migrate: keto-migrate:
@@ -129,7 +129,7 @@ services:
- OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect} - OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}
- OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret} - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}
volumes: volumes:
- ./docker/ory/oathkeeper:/etc/config/oathkeeper - ../config/.generated/ory/oathkeeper:/etc/config/oathkeeper
- oathkeeper_logs:/var/log/oathkeeper - oathkeeper_logs:/var/log/oathkeeper
entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"] entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"]
networks: networks:
@@ -152,9 +152,27 @@ services:
/bin/sh -c " /bin/sh -c "
apk add --no-cache curl; apk add --no-cache curl;
echo 'Wait for services...'; echo 'Wait for services...';
until curl -s http://kratos:4433/health/ready; do sleep 1; done; check_ready() {
until curl -s http://hydra:4444/health/ready; do sleep 1; done; name=\"$$1\";
until curl -s http://keto:4466/health/ready; do sleep 1; done; url=\"$$2\";
max=\"$${ORY_STACK_CHECK_MAX_ATTEMPTS:-60}\";
i=1;
while [ \"$$i\" -le \"$$max\" ]; do
if curl --connect-timeout 2 --max-time 3 -fsS \"$$url\" >/dev/null; then
echo \"Ory service ready: $$name\";
return 0;
fi;
echo \"Waiting for Ory service: $$name ($$i/$$max)\";
i=$$((i + 1));
sleep 1;
done;
echo \"ERROR: Ory service not ready: $$name after $$max attempts ($$url)\" >&2;
echo \"ERROR: Check service logs: docker logs ory_$$name\" >&2;
return 1;
};
check_ready kratos http://kratos:4433/health/ready || exit 1;
check_ready hydra http://hydra:4444/health/ready || exit 1;
check_ready keto http://keto:4466/health/ready || exit 1;
echo 'Ory Stack is fully operational!';" echo 'Ory Stack is fully operational!';"
depends_on: depends_on:
- kratos - kratos

View File

@@ -1,4 +1,4 @@
dsn: ${DSN} dsn: ${HYDRA_DSN}
serve: serve:
cookies: cookies:
@@ -77,7 +77,7 @@ urls:
secrets: secrets:
system: system:
- ${SECRETS_SYSTEM} - ${HYDRA_SYSTEM_SECRET}
webfinger: webfinger:
oidc_discovery: oidc_discovery:

View File

@@ -1,5 +1,5 @@
version: v0.11.0 version: v0.11.0
dsn: ${DSN} dsn: ${KETO_DSN}
serve: serve:
read: read:
host: 0.0.0.0 host: 0.0.0.0

View File

@@ -1,21 +1,21 @@
version: v26.2.0 version: v26.2.0
dsn: ${DSN} dsn: ${KRATOS_DSN}
serve: serve:
public: public:
base_url: ${KRATOS_BROWSER_URL} base_url: http://localhost:4433/
cors: cors:
enabled: true enabled: true
allowed_origins: allowed_origins:
- ${USERFRONT_URL} - http://localhost:5000
- ${ADMINFRONT_URL} - http://localhost:5173
- ${DEVFRONT_URL} - http://localhost:5174
- ${ORGFRONT_URL} - http://localhost:5175
- http://backend:3000 - http://backend:3000
- http://baron_backend:3000 - http://baron_backend:3000
admin: admin:
base_url: ${KRATOS_ADMIN_URL} base_url: http://localhost:4434/
session: session:
cookie: cookie:
@@ -24,22 +24,20 @@ session:
path: / path: /
selfservice: selfservice:
default_browser_return_url: ${KRATOS_UI_URL} default_browser_return_url: http://localhost:5000/
allowed_return_urls: allowed_return_urls:
- ${KRATOS_UI_URL} - http://localhost:5000
- ${KRATOS_UI_URL}/ - http://localhost:5000/
- ${USERFRONT_URL} - http://localhost:5000/ko
- ${USERFRONT_URL}/ - http://localhost:5000/ko/
- ${USERFRONT_URL}/ko - http://localhost:5000/en
- ${USERFRONT_URL}/ko/ - http://localhost:5000/en/
- ${USERFRONT_URL}/en - http://localhost:5000/auth/callback
- ${USERFRONT_URL}/en/ - http://localhost:5000/ko/auth/callback
- ${USERFRONT_URL}/auth/callback - http://localhost:5000/en/auth/callback
- ${USERFRONT_URL}/ko/auth/callback - http://localhost:5173/auth/callback
- ${USERFRONT_URL}/en/auth/callback - http://localhost:5174/auth/callback
- ${ADMINFRONT_URL}/auth/callback - http://localhost:5175/auth/callback
- ${DEVFRONT_URL}/auth/callback
- ${ORGFRONT_URL}/auth/callback
methods: methods:
password: password:
@@ -52,24 +50,24 @@ selfservice:
flows: flows:
error: error:
ui_url: ${KRATOS_UI_URL}/error ui_url: http://localhost:5000/error
settings: settings:
ui_url: ${KRATOS_UI_URL}/error?error=settings_disabled ui_url: http://localhost:5000/error?error=settings_disabled
privileged_session_max_age: 15m privileged_session_max_age: 15m
recovery: recovery:
ui_url: ${KRATOS_UI_URL}/recovery ui_url: http://localhost:5000/recovery
use: code use: code
verification: verification:
ui_url: ${KRATOS_UI_URL}/verification ui_url: http://localhost:5000/verification
use: code use: code
logout: logout:
after: after:
default_browser_return_url: ${KRATOS_UI_URL}/login default_browser_return_url: http://localhost:5000/login
login: login:
ui_url: ${KRATOS_UI_URL}/login ui_url: http://localhost:5000/login
lifespan: 10m lifespan: 10m
registration: registration:
ui_url: ${KRATOS_UI_URL}/registration ui_url: http://localhost:5000/registration
lifespan: 10m lifespan: 10m
log: log:

View File

@@ -114,7 +114,7 @@ services:
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
volumes: volumes:
- ./docker/ory/kratos:/etc/config/kratos - ./config/.generated/ory/kratos:/etc/config/kratos
command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes command: migrate sql up -e -c /etc/config/kratos/kratos.yml --yes
depends_on: depends_on:
postgres_ory: postgres_ory:
@@ -140,7 +140,7 @@ services:
- KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration - KRATOS_SELFSERVICE_FLOWS_REGISTRATION_UI_URL=${KRATOS_UI_URL}/registration
- KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login - KRATOS_SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=${KRATOS_UI_URL}/login
volumes: volumes:
- ./docker/ory/kratos:/etc/config/kratos - ./config/.generated/ory/kratos:/etc/config/kratos
command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
depends_on: depends_on:
kratos-migrate: kratos-migrate:
@@ -171,7 +171,7 @@ services:
- URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error} - URLS_ERROR=${HYDRA_ERROR_URL:-${USERFRONT_URL}/error}
- SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD} - SECRETS_SYSTEM=${ORY_POSTGRES_PASSWORD}
volumes: volumes:
- ./docker/ory/hydra:/etc/config/hydra - ./config/.generated/ory/hydra:/etc/config/hydra
command: serve -c /etc/config/hydra/hydra.yml all --dev command: serve -c /etc/config/hydra/hydra.yml all --dev
depends_on: depends_on:
hydra-migrate: hydra-migrate:
@@ -185,7 +185,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./docker/ory/keto:/etc/config/keto - ./config/.generated/ory/keto:/etc/config/keto
command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"] command: ["migrate", "up", "-c", "/etc/config/keto/keto.yml", "--yes"]
depends_on: depends_on:
postgres_ory: postgres_ory:
@@ -199,7 +199,7 @@ services:
environment: environment:
- DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20 - DSN=postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB:-ory_keto}?sslmode=disable&max_conns=20
volumes: volumes:
- ./docker/ory/keto:/etc/config/keto - ./config/.generated/ory/keto:/etc/config/keto
command: serve -c /etc/config/keto/keto.yml command: serve -c /etc/config/keto/keto.yml
depends_on: depends_on:
keto-migrate: keto-migrate:
@@ -236,7 +236,7 @@ services:
- OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect} - OATHKEEPER_INTROSPECT_CLIENT_ID=${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}
- OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret} - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}
volumes: volumes:
- ./docker/ory/oathkeeper:/etc/config/oathkeeper - ./config/.generated/ory/oathkeeper:/etc/config/oathkeeper
- oathkeeper_logs:/var/log/oathkeeper - oathkeeper_logs:/var/log/oathkeeper
entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"] entrypoint: ["/etc/config/oathkeeper/entrypoint.sh"]
networks: networks:
@@ -271,9 +271,27 @@ services:
/bin/sh -c " /bin/sh -c "
apk add --no-cache curl; apk add --no-cache curl;
echo 'Wait for services...'; echo 'Wait for services...';
until curl -s http://kratos:4433/health/ready; do sleep 1; done; check_ready() {
until curl -s http://hydra:4444/health/ready; do sleep 1; done; name=\"$$1\";
until curl -s http://keto:4466/health/ready; do sleep 1; done; url=\"$$2\";
max=\"$${ORY_STACK_CHECK_MAX_ATTEMPTS:-60}\";
i=1;
while [ \"$$i\" -le \"$$max\" ]; do
if curl --connect-timeout 2 --max-time 3 -fsS \"$$url\" >/dev/null; then
echo \"Ory service ready: $$name\";
return 0;
fi;
echo \"Waiting for Ory service: $$name ($$i/$$max)\";
i=$$((i + 1));
sleep 1;
done;
echo \"ERROR: Ory service not ready: $$name after $$max attempts ($$url)\" >&2;
echo \"ERROR: Check service logs: docker logs ory_$$name\" >&2;
return 1;
};
check_ready kratos http://kratos:4433/health/ready || exit 1;
check_ready hydra http://hydra:4444/health/ready || exit 1;
check_ready keto http://keto:4466/health/ready || exit 1;
echo 'Ory Stack is fully operational!';" echo 'Ory Stack is fully operational!';"
depends_on: depends_on:
- kratos - kratos

View File

@@ -5,7 +5,7 @@
## 1. 준비 사항 ## 1. 준비 사항
테스트를 실행하기 위해 다음 도구들이 설치되어 있어야 합니다. 테스트를 실행하기 위해 다음 도구들이 설치되어 있어야 합니다.
- **Docker & Docker Compose** (백엔드 인프라 의존성용) - **Docker & Docker Compose** (백엔드 인프라 의존성용)
- **Go 1.25+** - **Go 1.26.2+**
- **Flutter SDK** - **Flutter SDK**
- **Node.js 24 LTS+** - **Node.js 24 LTS+**

View File

@@ -88,7 +88,7 @@ flowchart
``` ```
### 1. Backend (Go Fiber) ### 1. Backend (Go Fiber)
- **Language**: Go 1.25+ - **Language**: Go 1.26.2+
- **Framework**: Fiber v2.25+ - **Framework**: Fiber v2.25+
- **Database**: - **Database**:
- **ClickHouse**: 감사 로그 (고성능 데이터 수집) - **ClickHouse**: 감사 로그 (고성능 데이터 수집)

View File

@@ -2,7 +2,7 @@
set -euo pipefail set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUTPUT_DIR="$ROOT_DIR/.generated" OUTPUT_DIR="$ROOT_DIR/config/.generated"
OUTPUT_FILE="$OUTPUT_DIR/auth-config.env" OUTPUT_FILE="$OUTPUT_DIR/auth-config.env"
MODE="${1:-build}" MODE="${1:-build}"

100
scripts/render_ory_config.sh Executable file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUTPUT_DIR="${ORY_CONFIG_OUTPUT_DIR:-$ROOT_DIR/config/.generated/ory}"
TEMPLATE_ROOT="${ORY_CONFIG_TEMPLATE_ROOT:-$ROOT_DIR/docker/ory}"
load_env_file() {
local env_file="$1"
if [[ -f "$env_file" ]]; then
set -a
# shellcheck disable=SC1090
source "$env_file"
set +a
fi
}
fail() {
echo "[ory-config] ERROR: $1" >&2
exit 1
}
render_template() {
local src="$1"
local dst="$2"
mkdir -p "$(dirname "$dst")"
perl -pe '
s/\$\{([A-Za-z_][A-Za-z0-9_]*)(:-([^}]*))?\}/
exists $ENV{$1} ? $ENV{$1} : defined $3 ? $3 : die "missing env var: $1\n"
/gex
' "$src" > "$dst"
}
copy_if_exists() {
local src="$1"
local dst="$2"
if [[ -e "$src" ]]; then
mkdir -p "$(dirname "$dst")"
cp -a "$src" "$dst"
fi
}
if [[ -n "${ORY_CONFIG_ENV_FILES:-}" ]]; then
IFS=':' read -r -a env_files <<<"$ORY_CONFIG_ENV_FILES"
for env_file in "${env_files[@]}"; do
load_env_file "$env_file"
done
else
load_env_file "$ROOT_DIR/.env"
load_env_file "$ROOT_DIR/config/.generated/auth-config.env"
fi
ORY_POSTGRES_USER="${ORY_POSTGRES_USER:-ory}"
ORY_POSTGRES_PASSWORD="${ORY_POSTGRES_PASSWORD:-secret}"
KRATOS_DB="${KRATOS_DB:-ory_kratos}"
HYDRA_DB="${HYDRA_DB:-ory_hydra}"
KETO_DB="${KETO_DB:-ory_keto}"
KRATOS_DSN="${KRATOS_DSN:-postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KRATOS_DB}?sslmode=disable&max_conns=20}"
HYDRA_DSN="${HYDRA_DSN:-postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${HYDRA_DB}?sslmode=disable&max_conns=20}"
KETO_DSN="${KETO_DSN:-postgres://${ORY_POSTGRES_USER}:${ORY_POSTGRES_PASSWORD}@postgres_ory:5432/${KETO_DB}?sslmode=disable&max_conns=20}"
HYDRA_SYSTEM_SECRET="${HYDRA_SYSTEM_SECRET:-${SECRETS_SYSTEM:-${ORY_POSTGRES_PASSWORD}}}"
OATHKEEPER_INTROSPECT_CLIENT_ID="${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}"
OATHKEEPER_INTROSPECT_CLIENT_SECRET="${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}"
export KRATOS_DSN HYDRA_DSN KETO_DSN HYDRA_SYSTEM_SECRET
export OATHKEEPER_INTROSPECT_CLIENT_ID OATHKEEPER_INTROSPECT_CLIENT_SECRET
rm -rf "$OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"
render_template "$TEMPLATE_ROOT/kratos/kratos.yml.template" "$OUTPUT_DIR/kratos/kratos.yml"
copy_if_exists "$TEMPLATE_ROOT/kratos/identity.schema.json" "$OUTPUT_DIR/kratos/identity.schema.json"
copy_if_exists "$TEMPLATE_ROOT/kratos/courier-http.jsonnet" "$OUTPUT_DIR/kratos/courier-http.jsonnet"
if [[ -d "$TEMPLATE_ROOT/kratos/courier-templates" ]]; then
mkdir -p "$OUTPUT_DIR/kratos"
cp -a "$TEMPLATE_ROOT/kratos/courier-templates" "$OUTPUT_DIR/kratos/courier-templates"
fi
render_template "$TEMPLATE_ROOT/hydra/hydra.yml.template" "$OUTPUT_DIR/hydra/hydra.yml"
render_template "$TEMPLATE_ROOT/keto/keto.yml.template" "$OUTPUT_DIR/keto/keto.yml"
copy_if_exists "$TEMPLATE_ROOT/keto/namespaces.ts" "$OUTPUT_DIR/keto/namespaces.ts"
copy_if_exists "$TEMPLATE_ROOT/keto/namespaces.yml" "$OUTPUT_DIR/keto/namespaces.yml"
render_template "$TEMPLATE_ROOT/oathkeeper/oathkeeper.yml.template" "$OUTPUT_DIR/oathkeeper/oathkeeper.yml"
copy_if_exists "$TEMPLATE_ROOT/oathkeeper/entrypoint.sh" "$OUTPUT_DIR/oathkeeper/entrypoint.sh"
chmod +x "$OUTPUT_DIR/oathkeeper/entrypoint.sh"
for rules_file in "$TEMPLATE_ROOT"/oathkeeper/rules*.json; do
[[ -e "$rules_file" ]] || continue
copy_if_exists "$rules_file" "$OUTPUT_DIR/oathkeeper/$(basename "$rules_file")"
done
if find "$OUTPUT_DIR" -type f \( -name '*.yml' -o -name '*.yaml' -o -name '*.json' -o -name '*.toml' \) -print0 | xargs -0 grep -n '\${' >/tmp/ory-render-unresolved.$$ 2>/dev/null; then
cat /tmp/ory-render-unresolved.$$ >&2
rm -f /tmp/ory-render-unresolved.$$
fail "rendered Ory config contains unresolved placeholders"
fi
rm -f /tmp/ory-render-unresolved.$$
echo "[ory-config] wrote: $OUTPUT_DIR"

View File

@@ -0,0 +1,78 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TARGET_GO_VERSION="1.26.2"
GO_MOD="$ROOT_DIR/backend/go.mod"
BACKEND_DOCKERFILE="$ROOT_DIR/backend/Dockerfile"
LOCAL_COMPOSE="$ROOT_DIR/docker-compose.yaml"
STAGING_COMPOSE="$ROOT_DIR/docker/docker-compose.staging.template.yaml"
PULL_COMPOSE="$ROOT_DIR/docker/staging_pull_compose.template.yaml"
DEPLOY_TEMPLATE="$ROOT_DIR/deploy/templates/docker-compose.yaml"
README="$ROOT_DIR/README.md"
README_EN="$ROOT_DIR/README_en.md"
TEST_GUIDE="$ROOT_DIR/docs/TEST_GUIDE.md"
COMPLETION_REPORT="$ROOT_DIR/docs/개발완료보고서.md"
for file in \
"$GO_MOD" \
"$BACKEND_DOCKERFILE" \
"$LOCAL_COMPOSE" \
"$STAGING_COMPOSE" \
"$PULL_COMPOSE" \
"$DEPLOY_TEMPLATE" \
"$README" \
"$README_EN" \
"$TEST_GUIDE" \
"$COMPLETION_REPORT"
do
if [[ ! -f "$file" ]]; then
echo "ERROR: expected file not found: $file" >&2
exit 1
fi
done
if ! grep -Eq "^go ${TARGET_GO_VERSION}$" "$GO_MOD"; then
echo "ERROR: backend go.mod must use go ${TARGET_GO_VERSION}." >&2
exit 1
fi
if ! grep -Eq "^FROM golang:${TARGET_GO_VERSION}-alpine$" "$BACKEND_DOCKERFILE"; then
echo "ERROR: backend Dockerfile must use golang:${TARGET_GO_VERSION}-alpine." >&2
exit 1
fi
for file in "$LOCAL_COMPOSE" "$PULL_COMPOSE"; do
if ! grep -Fq "context: ./backend" "$file" && ! grep -Fq "context: ../../backend" "$file"; then
echo "ERROR: backend compose build context is missing in $file." >&2
exit 1
fi
done
for file in "$STAGING_COMPOSE" "$DEPLOY_TEMPLATE"; do
if ! grep -Eq "^[[:space:]]+backend:$" "$file"; then
echo "ERROR: backend service is missing in $file." >&2
exit 1
fi
done
legacy_refs="$(
grep -R -nE "golang:1\\.25|^go 1\\.25" \
"$ROOT_DIR/backend" \
"$ROOT_DIR/docker-compose.yaml" \
"$ROOT_DIR/docker" \
"$ROOT_DIR/deploy/templates" \
"$README" \
"$README_EN" \
"$TEST_GUIDE" \
"$COMPLETION_REPORT" || true
)"
if [[ -n "$legacy_refs" ]]; then
echo "ERROR: legacy backend Go version references remain." >&2
echo "$legacy_refs" >&2
exit 1
fi
echo "OK: backend Go base version policy is ${TARGET_GO_VERSION}"

View File

@@ -30,6 +30,11 @@ if ! grep -q "Ensuring Ory stack" <<<"$dry_run_dev"; then
exit 1 exit 1
fi fi
if ! grep -q "Rendering Ory config" <<<"$dry_run_dev"; then
echo "make dev must render Ory config before starting services." >&2
exit 1
fi
app_up_line="$( app_up_line="$(
grep -E "docker compose .* -f docker-compose.yaml up .*backend.*adminfront" <<<"$dry_run_dev" | tail -1 grep -E "docker compose .* -f docker-compose.yaml up .*backend.*adminfront" <<<"$dry_run_dev" | tail -1
)" )"
@@ -44,6 +49,11 @@ if grep -q -- " -d" <<<"$app_up_line"; then
exit 1 exit 1
fi fi
if ! grep -q -- " --build" <<<"$app_up_line"; then
echo "make dev must rebuild app service images before starting development containers." >&2
exit 1
fi
dry_run_up_dev="$( dry_run_up_dev="$(
make --dry-run --always-make -C "$repo_root" up-dev 2>&1 make --dry-run --always-make -C "$repo_root" up-dev 2>&1
)" )"
@@ -67,6 +77,20 @@ if ! grep -q "Starting App stack (backend/userfront/adminfront/devfront/orgfront
exit 1 exit 1
fi fi
if ! grep -q "Rendering Ory config" <<<"$dry_run_up_app"; then
echo "make up-app must render Ory config before starting services." >&2
exit 1
fi
up_app_line="$(
grep -E "docker compose .* -f docker-compose.yaml up .*backend.*adminfront.*devfront.*orgfront.*userfront|docker compose .* -f docker-compose.yaml up " <<<"$dry_run_up_app" | tail -1
)"
if ! grep -q -- " --build" <<<"$up_app_line"; then
echo "make up-app must rebuild app service images before starting containers." >&2
exit 1
fi
dry_run_up_all="$( dry_run_up_all="$(
make --dry-run --always-make -C "$repo_root" up-all 2>&1 make --dry-run --always-make -C "$repo_root" up-all 2>&1
)" )"
@@ -84,6 +108,16 @@ if ! grep -q "Starting ALL stacks (infra + ory + app)" <<<"$dry_run_up"; then
exit 1 exit 1
fi fi
if ! grep -q "config/.generated/auth-config.env" <<<"$dry_run_up"; then
echo "make up must use generated env from config/.generated." >&2
exit 1
fi
if ! grep -q "Rendering Ory config" <<<"$dry_run_up"; then
echo "make up must render Ory config before compose up." >&2
exit 1
fi
if ! grep -q "Ensuring Docker networks" <<<"$dry_run_up_all"; then if ! grep -q "Ensuring Docker networks" <<<"$dry_run_up_all"; then
echo "make up-all must ensure external Docker networks before compose up." >&2 echo "make up-all must ensure external Docker networks before compose up." >&2
exit 1 exit 1

View File

@@ -3,6 +3,8 @@ set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
"$repo_root/scripts/render_ory_config.sh" >/dev/null
docker run --rm \ docker run --rm \
-e ORY_CLICKHOUSE_USER=ory \ -e ORY_CLICKHOUSE_USER=ory \
-e ORY_CLICKHOUSE_PASSWORD=orypass \ -e ORY_CLICKHOUSE_PASSWORD=orypass \
@@ -14,12 +16,12 @@ if grep -q '/etc/config/oathkeeper/rules.active.json' "$repo_root/docker/ory/oat
exit 1 exit 1
fi fi
if ! grep -q 'file:///tmp/oathkeeper/rules.active.json' "$repo_root/docker/ory/oathkeeper/oathkeeper.yml"; then if ! grep -q 'file:///tmp/oathkeeper/rules.active.json' "$repo_root/config/.generated/ory/oathkeeper/oathkeeper.yml"; then
echo "ERROR: Oathkeeper config must load active rules from writable runtime storage." >&2 echo "ERROR: Oathkeeper config must load active rules from writable runtime storage." >&2
exit 1 exit 1
fi fi
if ! grep -q '^version: v26.2.0$' "$repo_root/docker/ory/kratos/kratos.yml"; then if ! grep -q '^version: v26.2.0$' "$repo_root/config/.generated/ory/kratos/kratos.yml"; then
echo "ERROR: Kratos config version must match the v26.2.0 runtime." >&2 echo "ERROR: Kratos config version must match the v26.2.0 runtime." >&2
exit 1 exit 1
fi fi

View File

@@ -67,6 +67,30 @@ for compose_file in "$repo_root/compose.ory.yaml" "$repo_root/docker/compose.ory
fi fi
done done
for stack_check_file in \
"$repo_root/compose.ory.yaml" \
"$repo_root/docker/compose.ory.yaml" \
"$repo_root/docker/staging_pull_compose.template.yaml" \
"$repo_root/deploy/templates/docker-compose.yaml"
do
if grep -q 'until curl -s http://' "$stack_check_file"; then
echo "ERROR: Ory stack check must not wait forever; use bounded readiness checks in $stack_check_file." >&2
exit 1
fi
if ! grep -q 'ORY_STACK_CHECK_MAX_ATTEMPTS' "$stack_check_file"; then
echo "ERROR: Ory stack check must expose ORY_STACK_CHECK_MAX_ATTEMPTS in $stack_check_file." >&2
exit 1
fi
if ! grep -q 'ERROR: Ory service not ready' "$stack_check_file"; then
echo "ERROR: Ory stack check must report the failed service name in $stack_check_file." >&2
exit 1
fi
if ! grep -q 'check_ready kratos .* || exit 1' "$stack_check_file"; then
echo "ERROR: Ory stack check must raise a non-zero exit when Kratos is not ready in $stack_check_file." >&2
exit 1
fi
done
for expected_url in \ for expected_url in \
"https://compose-policy.example.test/sso/oidc" \ "https://compose-policy.example.test/sso/oidc" \
"https://compose-policy.example.test/sso/login" \ "https://compose-policy.example.test/sso/login" \
@@ -189,17 +213,17 @@ done
deploy_template="$repo_root/deploy/templates/docker-compose.yaml" deploy_template="$repo_root/deploy/templates/docker-compose.yaml"
deploy_env_template="$repo_root/deploy/templates/.env.template" deploy_env_template="$repo_root/deploy/templates/.env.template"
deploy_gateway_template="$repo_root/deploy/templates/gateway/nginx.conf" deploy_gateway_template="$repo_root/deploy/templates/gateway/nginx.conf"
deploy_kratos_template="$repo_root/deploy/templates/ory/kratos/kratos.yml" deploy_kratos_template="$repo_root/deploy/templates/ory/kratos/kratos.yml.template"
deploy_oathkeeper_rules_template="$repo_root/deploy/templates/ory/oathkeeper/rules.json" deploy_oathkeeper_rules_template="$repo_root/deploy/templates/ory/oathkeeper/rules.json"
for required_template in \ for required_template in \
"$repo_root/deploy/templates/orgfront/vite.config.ts" \ "$repo_root/deploy/templates/orgfront/vite.config.ts" \
"$repo_root/deploy/templates/orgfront/auth.ts" \ "$repo_root/deploy/templates/orgfront/auth.ts" \
"$repo_root/docker/ory/init-db/01_create_dbs.sh" \ "$repo_root/docker/ory/init-db/01_create_dbs.sh" \
"$repo_root/docker/ory/hydra/hydra.yml" \ "$repo_root/docker/ory/hydra/hydra.yml.template" \
"$repo_root/docker/ory/keto/keto.yml" \ "$repo_root/docker/ory/keto/keto.yml.template" \
"$repo_root/docker/ory/oathkeeper/entrypoint.sh" \ "$repo_root/docker/ory/oathkeeper/entrypoint.sh" \
"$repo_root/docker/ory/oathkeeper/oathkeeper.yml" "$repo_root/docker/ory/oathkeeper/oathkeeper.yml.template"
do do
if [[ ! -f "$required_template" ]]; then if [[ ! -f "$required_template" ]]; then
echo "ERROR: deploy instance generation requires missing source file: $required_template" >&2 echo "ERROR: deploy instance generation requires missing source file: $required_template" >&2
@@ -214,8 +238,8 @@ fi
for prod_sensitive_file in \ for prod_sensitive_file in \
"$repo_root/docker/ory/oathkeeper/rules.prod.json" \ "$repo_root/docker/ory/oathkeeper/rules.prod.json" \
"$repo_root/docker/ory/kratos/kratos.yml" \ "$repo_root/docker/ory/kratos/kratos.yml.template" \
"$repo_root/deploy/templates/ory/kratos/kratos.yml" "$repo_root/deploy/templates/ory/kratos/kratos.yml.template"
do do
if grep -q "app\\.brsw\\.kr" "$prod_sensitive_file"; then if grep -q "app\\.brsw\\.kr" "$prod_sensitive_file"; then
echo "ERROR: Ory production-sensitive config must not hard-code app.brsw.kr: $prod_sensitive_file" >&2 echo "ERROR: Ory production-sensitive config must not hard-code app.brsw.kr: $prod_sensitive_file" >&2
@@ -223,6 +247,51 @@ do
fi fi
done done
for compose_file in "$repo_root/compose.ory.yaml" "$repo_root/docker/compose.ory.yaml" "$repo_root/docker/staging_pull_compose.template.yaml"; do
if grep -Eq './docker/ory/(kratos|hydra|keto|oathkeeper):/etc/config/' "$compose_file"; then
echo "ERROR: Ory compose must mount rendered config/.generated/ory config, not source templates: $compose_file" >&2
exit 1
fi
done
if grep -Eq '\./ory/(kratos|hydra|keto|oathkeeper):/etc/config/' "$deploy_template"; then
echo "ERROR: deploy template must mount rendered config/.generated/ory config, not source templates." >&2
exit 1
fi
if grep -q 'ory/generated' "$deploy_template" "$repo_root/deploy/create-instance.sh"; then
echo "ERROR: deploy template must use config/.generated/ory, not ory/generated." >&2
exit 1
fi
if ! grep -q '^render-ory-config:' "$repo_root/Makefile"; then
echo "ERROR: Makefile must render Ory config before starting Ory services." >&2
exit 1
fi
if ! grep -q 'scripts/render_ory_config.sh' "$repo_root/.gitea/workflows/staging_code_pull.yml"; then
echo "ERROR: staging code pull must render Ory config before docker compose up." >&2
exit 1
fi
"$repo_root/scripts/render_ory_config.sh" >/dev/null
for generated_config in \
"$repo_root/config/.generated/ory/kratos/kratos.yml" \
"$repo_root/config/.generated/ory/hydra/hydra.yml" \
"$repo_root/config/.generated/ory/keto/keto.yml" \
"$repo_root/config/.generated/ory/oathkeeper/oathkeeper.yml"
do
if [[ ! -f "$generated_config" ]]; then
echo "ERROR: Ory rendered config is missing: $generated_config" >&2
exit 1
fi
if grep -q '\${' "$generated_config"; then
echo "ERROR: Ory rendered config must not contain placeholders: $generated_config" >&2
exit 1
fi
done
for service in kratos-migrate kratos hydra-migrate hydra keto-migrate keto oathkeeper_logs_init oathkeeper; do for service in kratos-migrate kratos hydra-migrate hydra keto-migrate keto oathkeeper_logs_init oathkeeper; do
if ! grep -q "^ $service:" "$deploy_template"; then if ! grep -q "^ $service:" "$deploy_template"; then
echo "ERROR: deploy template Ory stack must include service: $service" >&2 echo "ERROR: deploy template Ory stack must include service: $service" >&2