From d06edd03c0313477c20513d3a3ea29b1a84b65e8 Mon Sep 17 00:00:00 2001 From: chan Date: Fri, 6 Feb 2026 17:10:57 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=B4=EC=A0=84=EC=9D=98=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/staging_release.yml | 231 +++++++++++---------------- 1 file changed, 92 insertions(+), 139 deletions(-) diff --git a/.gitea/workflows/staging_release.yml b/.gitea/workflows/staging_release.yml index 6426bfae..24da8f3e 100644 --- a/.gitea/workflows/staging_release.yml +++ b/.gitea/workflows/staging_release.yml @@ -11,16 +11,13 @@ on: jobs: deploy-staging: runs-on: ubuntu-latest - steps: - name: Checkout code uses: actions/checkout@v4 - - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.STAGE_SSH_PRIVATE_KEY }} - - name: Deploy to Staging env: IMAGE_TAG: ${{ github.event.inputs.rc_version_tag }} @@ -28,163 +25,119 @@ jobs: USERFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/userfront ADMINFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/adminfront DEVFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/devfront - DEPLOY_PATH: ${{ vars.STAGE_DEPLOY_PATH }} STAGE_HOST: ${{ vars.STAGE_HOST }} STAGE_USER: ${{ vars.STAGE_USER }} - HARBOR_ENDPOINT: ${{ vars.HARBOR_ENDPOINT }} HARBOR_ROBOT_ACCOUNT: ${{ vars.HARBOR_ROBOT_ACCOUNT }} HARBOR_ROBOT_KEY: ${{ secrets.HARBOR_ROBOT_KEY }} - run: | set -euo pipefail - - echo "STAGE_USER=${STAGE_USER}" - echo "STAGE_HOST=${STAGE_HOST}" - echo "DEPLOY_PATH=${DEPLOY_PATH}" + echo "DEBUG: STAGE_USER='${STAGE_USER}'" + echo "DEBUG: STAGE_HOST='${STAGE_HOST}'" + echo "DEBUG: DEPLOY_PATH='${DEPLOY_PATH}'" if [ -z "${STAGE_USER}" ] || [ -z "${STAGE_HOST}" ] || [ -z "${DEPLOY_PATH}" ]; then - echo "::error::Missing required staging variables" + echo "::error::Missing required vars (STAGE_USER/STAGE_HOST/DEPLOY_PATH). Check Gitea repo variables." exit 1 fi ssh-keyscan -H "${STAGE_HOST}" >> ~/.ssh/known_hosts ssh "${STAGE_USER}@${STAGE_HOST}" "mkdir -p '${DEPLOY_PATH}'" - # ---------- create .env ---------- + # Create .env file using HEREDOC cat <<'EOF' > .env - APP_ENV=stage - TZ=Asia/Seoul - IDP_PROVIDER=ory +APP_ENV=stage +TZ=Asia/Seoul +IDP_PROVIDER=ory +DB_PORT=${{ vars.DB_PORT }} +CLICKHOUSE_PORT_HTTP=${{ vars.CLICKHOUSE_PORT_HTTP }} +CLICKHOUSE_PORT_NATIVE=${{ vars.CLICKHOUSE_PORT_NATIVE }} +BACKEND_PORT=${{ vars.BACKEND_PORT }} +ADMINFRONT_PORT=${{ vars.ADMINFRONT_PORT }} +DEVFRONT_PORT=${{ vars.DEVFRONT_PORT }} +USERFRONT_PORT=${{ vars.USERFRONT_PORT }} +DB_USER=${{ vars.DB_USER }} +DB_PASSWORD=${{ secrets.STG_DB_PASSWORD }} +DB_NAME=${{ vars.DB_NAME }} +COOKIE_SECRET=${{ secrets.STG_COOKIE_SECRET }} +JWT_SECRET=${{ secrets.STG_JWT_SECRET }} +REDIS_ADDR=${{ vars.REDIS_ADDR }} +CORS_ALLOWED_ORIGINS=${{ vars.CORS_ALLOWED_ORIGINS }} +AUDIT_WORKER_COUNT=5 +AUDIT_QUEUE_SIZE=2000 +PROFILE_CACHE_TTL=${{ vars.PROFILE_CACHE_TTL }} +DESCOPE_PROJECT_ID=${{ vars.DESCOPE_PROJECT_ID }} +DESCOPE_MANAGEMENT_KEY=${{ secrets.DESCOPE_MANAGEMENT_KEY }} +DESCOPE_TEST_ACCOUNT=${{ vars.DESCOPE_TEST_ACCOUNT }} +NAVER_CLOUD_ACCESS_KEY=${{ vars.NAVER_CLOUD_ACCESS_KEY }} +NAVER_CLOUD_SECRET_KEY=${{ secrets.NAVER_CLOUD_SECRET_KEY }} +NAVER_CLOUD_SERVICE_ID=${{ vars.NAVER_CLOUD_SERVICE_ID }} +NAVER_SENDER_PHONE_NUMBER=${{ vars.NAVER_SENDER_PHONE_NUMBER }} +AWS_REGION=${{ vars.AWS_REGION }} +AWS_ACCESS_KEY_ID=${{ vars.AWS_ACCESS_KEY_ID }} +AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} +AWS_SES_SENDER=${{ vars.AWS_SES_SENDER }} +ADMIN_EMAIL=${{ vars.ADMIN_EMAIL }} +ADMIN_PASSWORD=${{ secrets.STG_ADMIN_PASSWORD }} +USERFRONT_URL=${{ vars.USERFRONT_URL }} +BACKEND_URL=${{ vars.BACKEND_URL }} +OATHKEEPER_PUBLIC_URL=${{ vars.OATHKEEPER_PUBLIC_URL }} +ORY_POSTGRES_TAG=${{ vars.ORY_POSTGRES_TAG }} +ORY_POSTGRES_USER=${{ vars.ORY_POSTGRES_USER }} +ORY_POSTGRES_PASSWORD=${{ secrets.STG_ORY_POSTGRES_PASSWORD }} +ORY_POSTGRES_DB=${{ vars.ORY_POSTGRES_DB }} +KRATOS_DB=${{ vars.KRATOS_DB }} +HYDRA_DB=${{ vars.HYDRA_DB }} +KETO_DB=${{ vars.KETO_DB }} +KRATOS_VERSION=${{ vars.KRATOS_VERSION }} +KRATOS_UI_NODE_VERSION=${{ vars.KRATOS_UI_NODE_VERSION }} +HYDRA_VERSION=${{ vars.HYDRA_VERSION }} +KETO_VERSION=${{ vars.KETO_VERSION }} +ORY_SDK_URL=${{ vars.ORY_SDK_URL }} +KRATOS_PUBLIC_URL=${{ vars.KRATOS_PUBLIC_URL }} +KRATOS_ADMIN_URL=${{ vars.KRATOS_ADMIN_URL }} +KRATOS_BROWSER_URL=${{ vars.KRATOS_BROWSER_URL }} +KRATOS_UI_URL=${{ vars.KRATOS_UI_URL }} +HYDRA_ADMIN_URL=${{ vars.HYDRA_ADMIN_URL }} +HYDRA_PUBLIC_URL=${{ vars.HYDRA_PUBLIC_URL }} +JWKS_URL=${{ vars.JWKS_URL }} +OATHKEEPER_VERSION=${{ vars.OATHKEEPER_VERSION }} +OATHKEEPER_UID=${{ vars.OATHKEEPER_UID }} +OATHKEEPER_GID=${{ vars.OATHKEEPER_GID }} +OATHKEEPER_HEALTH_URL=${{ vars.OATHKEEPER_HEALTH_URL }} +OATHKEEPER_HEALTH_INTERVAL_SECONDS=${{ vars.OATHKEEPER_HEALTH_INTERVAL_SECONDS }} +OATHKEEPER_HEALTH_TIMEOUT_SECONDS=${{ vars.OATHKEEPER_HEALTH_TIMEOUT_SECONDS }} +OATHKEEPER_HEALTH_ENABLED=${{ vars.OATHKEEPER_HEALTH_ENABLED }} +CSRF_COOKIE_NAME=${{ vars.CSRF_COOKIE_NAME }} +CSRF_COOKIE_SECRET=${{ secrets.STG_CSRF_COOKIE_SECRET }} +OATHKEEPER_INTROSPECT_CLIENT_ID=${{ vars.OATHKEEPER_INTROSPECT_CLIENT_ID }} +OATHKEEPER_INTROSPECT_CLIENT_SECRET=${{ secrets.STG_OATHKEEPER_INTROSPECT_CLIENT_SECRET }} +EOF - DB_PORT=${{ vars.DB_PORT }} - CLICKHOUSE_PORT_HTTP=${{ vars.CLICKHOUSE_PORT_HTTP }} - CLICKHOUSE_PORT_NATIVE=${{ vars.CLICKHOUSE_PORT_NATIVE }} + # Copy artifacts to remote + scp docker/docker-compose.staging.template.yaml .env "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/" + scp docker/compose.infra.yaml "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/compose.infra.yml" + scp docker/compose.ory.yaml "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/compose.ory.yml" + scp -r docker/ory "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/docker/" - BACKEND_PORT=${{ vars.BACKEND_PORT }} - ADMINFRONT_PORT=${{ vars.ADMINFRONT_PORT }} - DEVFRONT_PORT=${{ vars.DEVFRONT_PORT }} - USERFRONT_PORT=${{ vars.USERFRONT_PORT }} + # Execute remote deployment script + ssh "${STAGE_USER}@${STAGE_HOST}" 'bash -s' </dev/null 2>&1 || docker network create "\$net" + done - REDIS_ADDR=${{ vars.REDIS_ADDR }} - CORS_ALLOWED_ORIGINS=${{ vars.CORS_ALLOWED_ORIGINS }} + set -a + . ./.env + set +a - AUDIT_WORKER_COUNT=5 - AUDIT_QUEUE_SIZE=2000 - PROFILE_CACHE_TTL=${{ vars.PROFILE_CACHE_TTL }} + envsubst '\$BACKEND_IMAGE_NAME \$ADMINFRONT_IMAGE_NAME \$DEVFRONT_IMAGE_NAME \$USERFRONT_IMAGE_NAME \$IMAGE_TAG' < docker-compose.staging.template.yaml > docker-compose.yml - DESCOPE_PROJECT_ID=${{ vars.DESCOPE_PROJECT_ID }} - DESCOPE_MANAGEMENT_KEY=${{ secrets.DESCOPE_MANAGEMENT_KEY }} - DESCOPE_TEST_ACCOUNT=${{ vars.DESCOPE_TEST_ACCOUNT }} - - NAVER_CLOUD_ACCESS_KEY=${{ vars.NAVER_CLOUD_ACCESS_KEY }} - NAVER_CLOUD_SECRET_KEY=${{ secrets.NAVER_CLOUD_SECRET_KEY }} - NAVER_CLOUD_SERVICE_ID=${{ vars.NAVER_CLOUD_SERVICE_ID }} - NAVER_SENDER_PHONE_NUMBER=${{ vars.NAVER_SENDER_PHONE_NUMBER }} - - AWS_REGION=${{ vars.AWS_REGION }} - AWS_ACCESS_KEY_ID=${{ vars.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_SES_SENDER=${{ vars.AWS_SES_SENDER }} - - ADMIN_EMAIL=${{ vars.ADMIN_EMAIL }} - ADMIN_PASSWORD=${{ secrets.STG_ADMIN_PASSWORD }} - - USERFRONT_URL=${{ vars.USERFRONT_URL }} - BACKEND_URL=${{ vars.BACKEND_URL }} - - OATHKEEPER_PUBLIC_URL=${{ vars.OATHKEEPER_PUBLIC_URL }} - - ORY_POSTGRES_TAG=${{ vars.ORY_POSTGRES_TAG }} - ORY_POSTGRES_USER=${{ vars.ORY_POSTGRES_USER }} - ORY_POSTGRES_PASSWORD=${{ secrets.STG_ORY_POSTGRES_PASSWORD }} - ORY_POSTGRES_DB=${{ vars.ORY_POSTGRES_DB }} - - KRATOS_DB=${{ vars.KRATOS_DB }} - HYDRA_DB=${{ vars.HYDRA_DB }} - KETO_DB=${{ vars.KETO_DB }} - - KRATOS_VERSION=${{ vars.KRATOS_VERSION }} - KRATOS_UI_NODE_VERSION=${{ vars.KRATOS_UI_NODE_VERSION }} - HYDRA_VERSION=${{ vars.HYDRA_VERSION }} - KETO_VERSION=${{ vars.KETO_VERSION }} - - ORY_SDK_URL=${{ vars.ORY_SDK_URL }} - KRATOS_PUBLIC_URL=${{ vars.KRATOS_PUBLIC_URL }} - KRATOS_ADMIN_URL=${{ vars.KRATOS_ADMIN_URL }} - KRATOS_BROWSER_URL=${{ vars.KRATOS_BROWSER_URL }} - KRATOS_UI_URL=${{ vars.KRATOS_UI_URL }} - - HYDRA_ADMIN_URL=${{ vars.HYDRA_ADMIN_URL }} - HYDRA_PUBLIC_URL=${{ vars.HYDRA_PUBLIC_URL }} - JWKS_URL=${{ vars.JWKS_URL }} - - OATHKEEPER_VERSION=${{ vars.OATHKEEPER_VERSION }} - OATHKEEPER_UID=${{ vars.OATHKEEPER_UID }} - OATHKEEPER_GID=${{ vars.OATHKEEPER_GID }} - OATHKEEPER_HEALTH_URL=${{ vars.OATHKEEPER_HEALTH_URL }} - OATHKEEPER_HEALTH_INTERVAL_SECONDS=${{ vars.OATHKEEPER_HEALTH_INTERVAL_SECONDS }} - OATHKEEPER_HEALTH_TIMEOUT_SECONDS=${{ vars.OATHKEEPER_HEALTH_TIMEOUT_SECONDS }} - OATHKEEPER_HEALTH_ENABLED=${{ vars.OATHKEEPER_HEALTH_ENABLED }} - - CSRF_COOKIE_NAME=${{ vars.CSRF_COOKIE_NAME }} - CSRF_COOKIE_SECRET=${{ secrets.STG_CSRF_COOKIE_SECRET }} - - OATHKEEPER_INTROSPECT_CLIENT_ID=${{ vars.OATHKEEPER_INTROSPECT_CLIENT_ID }} - OATHKEEPER_INTROSPECT_CLIENT_SECRET=${{ secrets.STG_OATHKEEPER_INTROSPECT_CLIENT_SECRET }} - EOF - - # ---------- copy files ---------- - scp docker/docker-compose.staging.template.yaml .env \ - "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/" - - scp docker/compose.infra.yaml \ - "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/compose.infra.yml" - - scp docker/compose.ory.yaml \ - "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/compose.ory.yml" - - scp -r docker/ory \ - "${STAGE_USER}@${STAGE_HOST}:${DEPLOY_PATH}/docker/" - - # ---------- deploy ---------- - echo "${HARBOR_ROBOT_KEY}" | ssh "${STAGE_USER}@${STAGE_HOST}" " - set -e - cd '${DEPLOY_PATH}' - - docker login '${HARBOR_ENDPOINT}' \ - -u '${HARBOR_ROBOT_ACCOUNT}' --password-stdin - - # 🔥 CREATE EXTERNAL NETWORKS - for net in baron_net public_net ory-net hydranet kratosnet; do - docker network inspect \"\$net\" >/dev/null 2>&1 || docker network create \"\$net\" - done - - set -a - . ./.env - set +a - - cp docker-compose.staging.template.yaml docker-compose.yml - sed -i "s|image: \${BACKEND_IMAGE_NAME}:\${IMAGE_TAG}|image: ${BACKEND_IMAGE_NAME}:${IMAGE_TAG}|g" docker-compose.yml - sed -i "s|image: \${ADMINFRONT_IMAGE_NAME}:\${IMAGE_TAG}|image: ${ADMINFRONT_IMAGE_NAME}:${IMAGE_TAG}|g" docker-compose.yml - sed -i "s|image: \${DEVFRONT_IMAGE_NAME}:\${IMAGE_TAG}|image: ${DEVFRONT_IMAGE_NAME}:${IMAGE_TAG}|g" docker-compose.yml - sed -i "s|image: \${USERFRONT_IMAGE_NAME}:\${IMAGE_TAG}|image: ${USERFRONT_IMAGE_NAME}:${IMAGE_TAG}|g" docker-compose.yml - - docker compose \ - -f compose.infra.yml \ - -f compose.ory.yml \ - -f docker-compose.yml pull - - docker compose \ - -f compose.infra.yml \ - -f compose.ory.yml \ - -f docker-compose.yml up -d --remove-orphans - " + docker compose -f compose.infra.yml -f compose.ory.yml -f docker-compose.yml pull + docker compose -f compose.infra.yml -f compose.ory.yml -f docker-compose.yml up -d --remove-orphans +EOF \ No newline at end of file