1
0
forked from baron/baron-sso

배포시 불필요한 변수 제거

This commit is contained in:
Lectom C Han
2026-02-11 08:55:50 +09:00
parent e0cf51893a
commit 731d4dfd93

View File

@@ -1,181 +1,165 @@
name: Release Baron SSO to Staging name: Release Baron SSO to Staging
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
rc_version_tag:
description: "The version tag to deploy to staging (e.g., v1.2601.1-RC1)"
required: true
type: string
jobs: jobs:
deploy-staging: deploy-staging:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup SSH - name: Setup SSH
uses: webfactory/ssh-agent@v0.9.0 uses: webfactory/ssh-agent@v0.9.0
with: with:
ssh-private-key: ${{ secrets.STAGE_SSH_PRIVATE_KEY }} ssh-private-key: ${{ secrets.STAGE_SSH_PRIVATE_KEY }}
- name: Deploy to Staging - name: Deploy to Staging
env: env:
IMAGE_TAG: ${{ github.event.inputs.rc_version_tag }} DEPLOY_PATH: ${{ vars.STAGE_DEPLOY_PATH }}
BACKEND_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/backend STAGE_HOST: ${{ vars.STAGE_HOST }}
USERFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/userfront STAGE_USER: ${{ vars.STAGE_USER }}
ADMINFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/adminfront run: |
DEVFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/devfront set -euo pipefail
# Staging-specific variables echo "DEBUG: STAGE_USER='${STAGE_USER}'"
DEPLOY_PATH: ${{ vars.STAGE_DEPLOY_PATH }} echo "DEBUG: STAGE_HOST='${STAGE_HOST}'"
STAGE_HOST: ${{ vars.STAGE_HOST }} echo "DEBUG: DEPLOY_PATH='${DEPLOY_PATH}'"
STAGE_USER: ${{ vars.STAGE_USER }}
HARBOR_ENDPOINT: ${{ vars.HARBOR_ENDPOINT }} # Sanity check
HARBOR_ROBOT_ACCOUNT: ${{ vars.HARBOR_ROBOT_ACCOUNT }} if [ -z "${STAGE_USER}" ] || [ -z "${STAGE_HOST}" ] || [ -z "${DEPLOY_PATH}" ]; then
HARBOR_ROBOT_KEY: ${{ secrets.HARBOR_ROBOT_KEY }} echo "::error::Missing required vars (STAGE_USER/STAGE_HOST/DEPLOY_PATH)."
run: | exit 1
set -euo pipefail fi
echo "DEBUG: STAGE_USER='${STAGE_USER}'" ssh-keyscan -H "${STAGE_HOST}" >> ~/.ssh/known_hosts
echo "DEBUG: STAGE_HOST='${STAGE_HOST}'" ssh "${STAGE_USER}@${STAGE_HOST}" "mkdir -p '${DEPLOY_PATH}'"
echo "DEBUG: DEPLOY_PATH='${DEPLOY_PATH}'"
# Sanity check # .env 파일 생성
if [ -z "${STAGE_USER}" ] || [ -z "${STAGE_HOST}" ] || [ -z "${DEPLOY_PATH}" ]; then cat <<'EOF' > .env
echo "::error::Missing required vars (STAGE_USER/STAGE_HOST/DEPLOY_PATH)." APP_ENV=${{ vars.APP_ENV }}
exit 1 TZ=Asia/Seoul
fi IDP_PROVIDER=ory
ssh-keyscan -H "${STAGE_HOST}" >> ~/.ssh/known_hosts # DB & Clickhouse
ssh "${STAGE_USER}@${STAGE_HOST}" "mkdir -p '${DEPLOY_PATH}'" DB_PORT=${{ vars.DB_PORT }}
CLICKHOUSE_PORT_HTTP=${{ vars.CLICKHOUSE_PORT_HTTP }}
# .env 파일 생성 CLICKHOUSE_PORT_NATIVE=${{ vars.CLICKHOUSE_PORT_NATIVE }}
cat <<'EOF' > .env CLICKHOUSE_HOST=${{ vars.CLICKHOUSE_HOST }}
APP_ENV=${{ vars.APP_ENV }} CLICKHOUSE_USER=${{ vars.CLICKHOUSE_USER }}
TZ=Asia/Seoul CLICKHOUSE_PASSWORD=${{ vars.CLICKHOUSE_PASSWORD }}
IDP_PROVIDER=ory
# DB & Clickhouse
DB_PORT=${{ vars.DB_PORT }}
CLICKHOUSE_PORT_HTTP=${{ vars.CLICKHOUSE_PORT_HTTP }}
CLICKHOUSE_PORT_NATIVE=${{ vars.CLICKHOUSE_PORT_NATIVE }}
CLICKHOUSE_HOST=${{ vars.CLICKHOUSE_HOST }}
CLICKHOUSE_USER=${{ vars.CLICKHOUSE_USER }}
CLICKHOUSE_PASSWORD=${{ vars.CLICKHOUSE_PASSWORD }}
BACKEND_PORT=${{ vars.BACKEND_PORT }} BACKEND_PORT=${{ vars.BACKEND_PORT }}
ADMINFRONT_PORT=${{ vars.ADMINFRONT_PORT }} ADMINFRONT_PORT=${{ vars.ADMINFRONT_PORT }}
DEVFRONT_PORT=${{ vars.DEVFRONT_PORT }} DEVFRONT_PORT=${{ vars.DEVFRONT_PORT }}
USERFRONT_PORT=${{ vars.USERFRONT_PORT }} USERFRONT_PORT=${{ vars.USERFRONT_PORT }}
OATHKEEPER_API_URL=${{ vars.OATHKEEPER_API_URL }} OATHKEEPER_API_URL=${{ vars.OATHKEEPER_API_URL }}
DB_USER=${{ vars.DB_USER }} DB_USER=${{ vars.DB_USER }}
DB_PASSWORD=${{ secrets.STG_DB_PASSWORD }} DB_PASSWORD=${{ secrets.STG_DB_PASSWORD }}
DB_NAME=${{ vars.DB_NAME }} DB_NAME=${{ vars.DB_NAME }}
COOKIE_SECRET=${{ secrets.STG_COOKIE_SECRET }} COOKIE_SECRET=${{ secrets.STG_COOKIE_SECRET }}
JWT_SECRET=${{ secrets.STG_JWT_SECRET }} JWT_SECRET=${{ secrets.STG_JWT_SECRET }}
REDIS_ADDR=${{ vars.REDIS_ADDR }} REDIS_ADDR=${{ vars.REDIS_ADDR }}
CORS_ALLOWED_ORIGINS=${{ vars.CORS_ALLOWED_ORIGINS }} CORS_ALLOWED_ORIGINS=${{ vars.CORS_ALLOWED_ORIGINS }}
AUDIT_WORKER_COUNT=5 AUDIT_WORKER_COUNT=5
AUDIT_QUEUE_SIZE=2000 AUDIT_QUEUE_SIZE=2000
PROFILE_CACHE_TTL=${{ vars.PROFILE_CACHE_TTL }} PROFILE_CACHE_TTL=${{ vars.PROFILE_CACHE_TTL }}
DESCOPE_TEST_ACCOUNT=${{ vars.DESCOPE_TEST_ACCOUNT }} DESCOPE_TEST_ACCOUNT=${{ vars.DESCOPE_TEST_ACCOUNT }}
NAVER_CLOUD_ACCESS_KEY=${{ vars.NAVER_CLOUD_ACCESS_KEY }} NAVER_CLOUD_ACCESS_KEY=${{ vars.NAVER_CLOUD_ACCESS_KEY }}
NAVER_CLOUD_SECRET_KEY=${{ secrets.NAVER_CLOUD_SECRET_KEY }} NAVER_CLOUD_SECRET_KEY=${{ secrets.NAVER_CLOUD_SECRET_KEY }}
NAVER_CLOUD_SERVICE_ID=${{ vars.NAVER_CLOUD_SERVICE_ID }} NAVER_CLOUD_SERVICE_ID=${{ vars.NAVER_CLOUD_SERVICE_ID }}
NAVER_SENDER_PHONE_NUMBER=${{ vars.NAVER_SENDER_PHONE_NUMBER }} NAVER_SENDER_PHONE_NUMBER=${{ vars.NAVER_SENDER_PHONE_NUMBER }}
AWS_REGION=${{ vars.AWS_REGION }} AWS_REGION=${{ vars.AWS_REGION }}
AWS_ACCESS_KEY_ID=${{ vars.AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID=${{ vars.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SES_SENDER=${{ vars.AWS_SES_SENDER }} AWS_SES_SENDER=${{ vars.AWS_SES_SENDER }}
ADMIN_EMAIL=${{ vars.ADMIN_EMAIL }} ADMIN_EMAIL=${{ vars.ADMIN_EMAIL }}
ADMIN_PASSWORD=${{ secrets.STG_ADMIN_PASSWORD }} ADMIN_PASSWORD=${{ secrets.STG_ADMIN_PASSWORD }}
USERFRONT_URL=${{ vars.USERFRONT_URL }} USERFRONT_URL=${{ vars.USERFRONT_URL }}
BACKEND_URL=${{ vars.BACKEND_URL }} BACKEND_URL=${{ vars.BACKEND_URL }}
OATHKEEPER_PUBLIC_URL=${{ vars.OATHKEEPER_PUBLIC_URL }} OATHKEEPER_PUBLIC_URL=${{ vars.OATHKEEPER_PUBLIC_URL }}
ORY_POSTGRES_TAG=${{ vars.ORY_POSTGRES_TAG }} ORY_POSTGRES_TAG=${{ vars.ORY_POSTGRES_TAG }}
ORY_POSTGRES_USER=${{ vars.ORY_POSTGRES_USER }} ORY_POSTGRES_USER=${{ vars.ORY_POSTGRES_USER }}
ORY_POSTGRES_PASSWORD=${{ secrets.STG_ORY_POSTGRES_PASSWORD }} ORY_POSTGRES_PASSWORD=${{ secrets.STG_ORY_POSTGRES_PASSWORD }}
ORY_POSTGRES_DB=${{ vars.ORY_POSTGRES_DB }} ORY_POSTGRES_DB=${{ vars.ORY_POSTGRES_DB }}
KRATOS_DB=${{ vars.KRATOS_DB }} KRATOS_DB=${{ vars.KRATOS_DB }}
HYDRA_DB=${{ vars.HYDRA_DB }} HYDRA_DB=${{ vars.HYDRA_DB }}
KETO_DB=${{ vars.KETO_DB }} KETO_DB=${{ vars.KETO_DB }}
KRATOS_VERSION=${{ vars.KRATOS_VERSION }} KRATOS_VERSION=${{ vars.KRATOS_VERSION }}
KRATOS_UI_NODE_VERSION=${{ vars.KRATOS_UI_NODE_VERSION }} KRATOS_UI_NODE_VERSION=${{ vars.KRATOS_UI_NODE_VERSION }}
HYDRA_VERSION=${{ vars.HYDRA_VERSION }} HYDRA_VERSION=${{ vars.HYDRA_VERSION }}
KETO_VERSION=${{ vars.KETO_VERSION }} KETO_VERSION=${{ vars.KETO_VERSION }}
ORY_SDK_URL=${{ vars.ORY_SDK_URL }} ORY_SDK_URL=${{ vars.ORY_SDK_URL }}
KRATOS_PUBLIC_URL=${{ vars.KRATOS_PUBLIC_URL }} KRATOS_PUBLIC_URL=${{ vars.KRATOS_PUBLIC_URL }}
KRATOS_ADMIN_URL=${{ vars.KRATOS_ADMIN_URL }} KRATOS_ADMIN_URL=${{ vars.KRATOS_ADMIN_URL }}
KRATOS_BROWSER_URL=${{ vars.KRATOS_BROWSER_URL }} KRATOS_BROWSER_URL=${{ vars.KRATOS_BROWSER_URL }}
KRATOS_UI_URL=${{ vars.KRATOS_UI_URL }} KRATOS_UI_URL=${{ vars.KRATOS_UI_URL }}
HYDRA_ADMIN_URL=${{ vars.HYDRA_ADMIN_URL }} HYDRA_ADMIN_URL=${{ vars.HYDRA_ADMIN_URL }}
HYDRA_PUBLIC_URL=${{ vars.HYDRA_PUBLIC_URL }} HYDRA_PUBLIC_URL=${{ vars.HYDRA_PUBLIC_URL }}
JWKS_URL=${{ vars.JWKS_URL }} JWKS_URL=${{ vars.JWKS_URL }}
OATHKEEPER_VERSION=${{ vars.OATHKEEPER_VERSION }} OATHKEEPER_VERSION=${{ vars.OATHKEEPER_VERSION }}
OATHKEEPER_UID=${{ vars.OATHKEEPER_UID }} OATHKEEPER_UID=${{ vars.OATHKEEPER_UID }}
OATHKEEPER_GID=${{ vars.OATHKEEPER_GID }} OATHKEEPER_GID=${{ vars.OATHKEEPER_GID }}
OATHKEEPER_HEALTH_URL=${{ vars.OATHKEEPER_HEALTH_URL }} OATHKEEPER_HEALTH_URL=${{ vars.OATHKEEPER_HEALTH_URL }}
OATHKEEPER_HEALTH_INTERVAL_SECONDS=${{ vars.OATHKEEPER_HEALTH_INTERVAL_SECONDS }} OATHKEEPER_HEALTH_INTERVAL_SECONDS=${{ vars.OATHKEEPER_HEALTH_INTERVAL_SECONDS }}
OATHKEEPER_HEALTH_TIMEOUT_SECONDS=${{ vars.OATHKEEPER_HEALTH_TIMEOUT_SECONDS }} OATHKEEPER_HEALTH_TIMEOUT_SECONDS=${{ vars.OATHKEEPER_HEALTH_TIMEOUT_SECONDS }}
OATHKEEPER_HEALTH_ENABLED=${{ vars.OATHKEEPER_HEALTH_ENABLED }} OATHKEEPER_HEALTH_ENABLED=${{ vars.OATHKEEPER_HEALTH_ENABLED }}
CSRF_COOKIE_NAME=${{ vars.CSRF_COOKIE_NAME }} CSRF_COOKIE_NAME=${{ vars.CSRF_COOKIE_NAME }}
CSRF_COOKIE_SECRET=${{ secrets.STG_CSRF_COOKIE_SECRET }} CSRF_COOKIE_SECRET=${{ secrets.STG_CSRF_COOKIE_SECRET }}
# OATHKEEPER_INTROSPECT_CLIENT_ID=${{ vars.OATHKEEPER_INTROSPECT_CLIENT_ID }} # OATHKEEPER_INTROSPECT_CLIENT_ID=${{ vars.OATHKEEPER_INTROSPECT_CLIENT_ID }}
# OATHKEEPER_INTROSPECT_CLIENT_SECRET=${{ secrets.STG_OATHKEEPER_INTROSPECT_CLIENT_SECRET }} # OATHKEEPER_INTROSPECT_CLIENT_SECRET=${{ secrets.STG_OATHKEEPER_INTROSPECT_CLIENT_SECRET }}
EOF EOF
# 코드 업데이트 (Git) # 코드 업데이트 (Git)
ssh "${STAGE_USER}@${STAGE_HOST}" "mkdir -p '${DEPLOY_PATH}' && cd '${DEPLOY_PATH}' && \ ssh "${STAGE_USER}@${STAGE_HOST}" "mkdir -p '${DEPLOY_PATH}' && cd '${DEPLOY_PATH}' && \
git fetch origin main && \ git fetch origin main && \
git checkout -B main origin/main && \ git checkout -B main origin/main && \
git pull --ff-only" git pull --ff-only"
# .env 파일 복사 # .env 파일 복사
scp .env "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/" scp .env "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/"
# 배포 실행 # 배포 실행
echo "${HARBOR_ROBOT_KEY}" | ssh "${STAGE_USER}@${STAGE_HOST}" \ echo "${HARBOR_ROBOT_KEY}" | ssh "${STAGE_USER}@${STAGE_HOST}" \
"export DEPLOY_PATH='${DEPLOY_PATH}'; \ "export DEPLOY_PATH='${DEPLOY_PATH}'; \
export BACKEND_IMAGE_NAME='${BACKEND_IMAGE_NAME}'; \ export BACKEND_IMAGE_NAME='${BACKEND_IMAGE_NAME}'; \
export USERFRONT_IMAGE_NAME='${USERFRONT_IMAGE_NAME}'; \ export USERFRONT_IMAGE_NAME='${USERFRONT_IMAGE_NAME}'; \
export ADMINFRONT_IMAGE_NAME='${ADMINFRONT_IMAGE_NAME}'; \ export ADMINFRONT_IMAGE_NAME='${ADMINFRONT_IMAGE_NAME}'; \
export DEVFRONT_IMAGE_NAME='${DEVFRONT_IMAGE_NAME}'; \ export DEVFRONT_IMAGE_NAME='${DEVFRONT_IMAGE_NAME}'; \
export IMAGE_TAG='${IMAGE_TAG}'; \ export IMAGE_TAG='${IMAGE_TAG}'; \
export HARBOR_ENDPOINT='${HARBOR_ENDPOINT}'; \ export HARBOR_ENDPOINT='${HARBOR_ENDPOINT}'; \
export HARBOR_ROBOT_ACCOUNT='${HARBOR_ROBOT_ACCOUNT}'; \ export HARBOR_ROBOT_ACCOUNT='${HARBOR_ROBOT_ACCOUNT}'; \
cd \"\${DEPLOY_PATH}\"; \ cd \"\${DEPLOY_PATH}\"; \
docker login \"\${HARBOR_ENDPOINT}\" -u \"\${HARBOR_ROBOT_ACCOUNT}\" --password-stdin; \ docker login \"\${HARBOR_ENDPOINT}\" -u \"\${HARBOR_ROBOT_ACCOUNT}\" --password-stdin; \
set -a; . ./.env; set +a; \ set -a; . ./.env; set +a; \
# 네트워크 생성 # 네트워크 생성
for net in baron_net public_net ory-net hydranet kratosnet; do for net in baron_net public_net ory-net hydranet kratosnet; do
docker network inspect \"\$net\" >/dev/null 2>&1 || docker network create \"\$net\" docker network inspect \"\$net\" >/dev/null 2>&1 || docker network create \"\$net\"
done done
envsubst < docker/docker-compose.staging.template.yaml > docker-compose.yml; \ envsubst < docker/docker-compose.staging.template.yaml > docker-compose.yml; \
# [중요] 설정 파일 권한 문제 해결 (Ory 이미지는 root가 아닌 사용자로 실행됨) # [중요] 설정 파일 권한 문제 해결 (Ory 이미지는 root가 아닌 사용자로 실행됨)
chmod -R 777 docker/ory chmod -R 777 docker/ory
docker compose -f docker/compose.infra.yaml -f docker/compose.ory.yaml -f docker-compose.yml pull; \ docker compose -f docker/compose.infra.yaml -f docker/compose.ory.yaml -f docker-compose.yml pull; \
# [주의] DB 초기화 스크립트는 '새로운 볼륨'에서만 실행됨. # [주의] DB 초기화 스크립트는 '새로운 볼륨'에서만 실행됨.
# DB 초기화 문제를 확실히 해결하기 위해 기존 볼륨을 날리고 다시 띄움 (데이터 삭제됨 주의) # DB 초기화 문제를 확실히 해결하기 위해 기존 볼륨을 날리고 다시 띄움 (데이터 삭제됨 주의)
# 스테이징이므로 초기화 진행. 데이터 보존이 필요하면 이 줄 제거하고 수동으로 DB 만들어야 함. # 스테이징이므로 초기화 진행. 데이터 보존이 필요하면 이 줄 제거하고 수동으로 DB 만들어야 함.
docker compose -f docker/compose.infra.yaml -f docker/compose.ory.yaml -f docker-compose.yml down -v || true docker compose -f docker/compose.infra.yaml -f docker/compose.ory.yaml -f docker-compose.yml down || true
docker compose -f docker/compose.infra.yaml -f docker/compose.ory.yaml -f docker-compose.yml up -d --remove-orphans; \ docker compose -f docker/compose.infra.yaml -f docker/compose.ory.yaml -f docker-compose.yml up -d --remove-orphans; \
# 배포 후 상태 확인 (실패 시 로그 출력을 위함) # 배포 후 상태 확인 (실패 시 로그 출력을 위함)
sleep 10; \ sleep 10; \
if [ \$(docker inspect -f '{{.State.ExitCode}}' baron-sso-staging-kratos-migrate-1) -ne 0 ]; then \ if [ \$(docker inspect -f '{{.State.ExitCode}}' baron-sso-staging-kratos-migrate-1) -ne 0 ]; then \
echo 'Kratos Migrate Failed. Logs:'; \ echo 'Kratos Migrate Failed. Logs:'; \
docker logs baron-sso-staging-kratos-migrate-1; \ docker logs baron-sso-staging-kratos-migrate-1; \
exit 1; \ exit 1; \
fi" fi"