1
0
forked from baron/baron-sso

production 푸시 초안

This commit is contained in:
2026-06-18 11:02:48 +09:00
parent 33249eb229
commit a56d68896f
37 changed files with 3573 additions and 114 deletions

View File

@@ -0,0 +1,96 @@
name: Deploy Baron SSO Production Images
on:
workflow_dispatch:
inputs:
image_tag:
description: "배포할 공용 저장소 이미지 태그 (예: v1.2606.ab12)"
required: true
type: string
jobs:
deploy-production-images:
runs-on: ubuntu-latest
steps:
- name: Checkout deployment scripts and templates
uses: actions/checkout@v4
- name: Setup SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.PROD_SSH_PRIVATE_KEY }}
- name: Build production deployment bundle
env:
IMAGE_TAG: ${{ github.event.inputs.image_tag }}
IMAGE_DEPLOY_ENV: production
IMAGE_DEPLOY_INSTANCE_NAME: ${{ vars.PROD_INSTANCE_NAME }}
IMAGE_DEPLOY_PORT_PREFIX: ${{ vars.PROD_PORT_PREFIX }}
IMAGE_DEPLOY_PUBLIC_URL: ${{ vars.PROD_FRONTEND_URL }}
IMAGE_DEPLOY_COMPOSE_TEMPLATE: deploy/templates/docker-compose.images.yaml
IMAGE_DEPLOY_BUNDLE_FILE: prod-image-deploy-bundle.tgz
ADMINFRONT_URL: ${{ vars.ADMINFRONT_URL }}
DEVFRONT_URL: ${{ vars.DEVFRONT_URL }}
ORGFRONT_URL: ${{ vars.ORGFRONT_URL }}
VITE_OIDC_AUTHORITY: ${{ vars.VITE_OIDC_AUTHORITY }}
IMAGE_DEPLOY_DB_PORT: ${{ vars.PROD_DB_PORT }}
IMAGE_DEPLOY_REDIS_PORT: ${{ vars.PROD_REDIS_PORT }}
IMAGE_DEPLOY_CLICKHOUSE_PORT_HTTP: ${{ vars.PROD_CLICKHOUSE_PORT_HTTP }}
IMAGE_DEPLOY_CLICKHOUSE_PORT_NATIVE: ${{ vars.PROD_CLICKHOUSE_PORT_NATIVE }}
IMAGE_DEPLOY_BACKEND_PORT: ${{ vars.PROD_BACKEND_PORT }}
IMAGE_DEPLOY_FRONTEND_PORT: ${{ vars.PROD_FRONTEND_PORT }}
ADMINFRONT_PORT: ${{ vars.ADMINFRONT_PORT }}
DEVFRONT_PORT: ${{ vars.DEVFRONT_PORT }}
ORGFRONT_PORT: ${{ vars.ORGFRONT_PORT }}
IMAGE_DEPLOY_OATHKEEPER_PROXY_PORT: ${{ vars.PROD_OATHKEEPER_PROXY_PORT }}
IMAGE_DEPLOY_DOMAIN_SUFFIX: ${{ vars.PROD_DOMAIN_SUFFIX }}
ADMINFRONT_CALLBACK_URLS: ${{ vars.ADMINFRONT_CALLBACK_URLS }}
DEVFRONT_CALLBACK_URLS: ${{ vars.DEVFRONT_CALLBACK_URLS }}
ORGFRONT_CALLBACK_URLS: ${{ vars.ORGFRONT_CALLBACK_URLS }}
HYDRA_REFRESH_TOKEN_TTL: ${{ vars.HYDRA_REFRESH_TOKEN_TTL }}
ORY_POSTGRES_USER: ${{ vars.ORY_POSTGRES_USER }}
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 }}
HYDRA_VERSION: ${{ vars.HYDRA_VERSION }}
KETO_VERSION: ${{ vars.KETO_VERSION }}
OATHKEEPER_VERSION: ${{ vars.OATHKEEPER_VERSION }}
ORY_POSTGRES_TAG: ${{ vars.ORY_POSTGRES_TAG }}
OATHKEEPER_UID: ${{ vars.OATHKEEPER_UID }}
OATHKEEPER_GID: ${{ vars.OATHKEEPER_GID }}
OATHKEEPER_INTROSPECT_CLIENT_ID: ${{ vars.OATHKEEPER_INTROSPECT_CLIENT_ID }}
ADMIN_EMAIL: ${{ vars.ADMIN_EMAIL }}
HARBOR_HOSTNAME: ${{ vars.HARBOR_HOSTNAME }}
BACKEND_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/backend
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
ORGFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/orgfront
IMAGE_DEPLOY_DB_PASSWORD: ${{ secrets.PROD_DB_PASSWORD }}
IMAGE_DEPLOY_ORY_POSTGRES_PASSWORD: ${{ secrets.PROD_ORY_POSTGRES_PASSWORD }}
IMAGE_DEPLOY_OATHKEEPER_INTROSPECT_CLIENT_SECRET: ${{ secrets.PROD_OATHKEEPER_INTROSPECT_CLIENT_SECRET }}
IMAGE_DEPLOY_CLICKHOUSE_PASSWORD: ${{ secrets.PROD_CLICKHOUSE_PASSWORD }}
IMAGE_DEPLOY_COOKIE_SECRET: ${{ secrets.PROD_COOKIE_SECRET }}
IMAGE_DEPLOY_JWT_SECRET: ${{ secrets.PROD_JWT_SECRET }}
IMAGE_DEPLOY_CSRF_COOKIE_SECRET: ${{ secrets.PROD_CSRF_COOKIE_SECRET }}
IMAGE_DEPLOY_ADMIN_PASSWORD: ${{ secrets.PROD_ADMIN_PASSWORD }}
run: |
set -euo pipefail
# Same image tag contract as staging: production must consume the
# immutable image tag that already passed staging verification.
scripts/deploy/build_image_deploy_bundle.sh
- name: Upload bundle and run requested production image tag
env:
IMAGE_DEPLOY_BUNDLE_FILE: prod-image-deploy-bundle.tgz
DEPLOY_HOST: ${{ vars.PROD_HOST }}
DEPLOY_USER: ${{ vars.PROD_USER }}
DEPLOY_PATH: ${{ vars.PROD_DEPLOY_PATH }}
HARBOR_ENDPOINT: ${{ vars.HARBOR_ENDPOINT }}
HARBOR_ROBOT_ACCOUNT: ${{ vars.HARBOR_ROBOT_ACCOUNT }}
HARBOR_ROBOT_KEY: ${{ secrets.HARBOR_ROBOT_KEY }}
run: |
set -euo pipefail
scripts/deploy/upload_and_run_image_deploy.sh

View File

@@ -0,0 +1,182 @@
name: Publish Baron SSO Production Images
on:
workflow_dispatch:
inputs:
version_prefix:
description: "공용 저장소 이미지 태그 prefix (예: v1.2606, 최종 태그는 v1.2606.<커밋해시4자리>)"
required: true
type: string
jobs:
publish-images:
runs-on: ubuntu-latest
steps:
- name: Checkout dev branch
uses: actions/checkout@v4
with:
ref: dev
- name: Validate publish inputs
env:
VERSION_PREFIX: ${{ github.event.inputs.version_prefix }}
HARBOR_ENDPOINT: ${{ vars.HARBOR_ENDPOINT }}
HARBOR_HOSTNAME: ${{ vars.HARBOR_HOSTNAME }}
HARBOR_ROBOT_ACCOUNT: ${{ vars.HARBOR_ROBOT_ACCOUNT }}
HARBOR_ROBOT_KEY: ${{ secrets.HARBOR_ROBOT_KEY }}
ADMINFRONT_URL: ${{ vars.ADMINFRONT_URL }}
DEVFRONT_URL: ${{ vars.DEVFRONT_URL }}
ORGFRONT_URL: ${{ vars.ORGFRONT_URL }}
VITE_OIDC_AUTHORITY: ${{ vars.VITE_OIDC_AUTHORITY }}
run: |
set -euo pipefail
if ! printf '%s' "${VERSION_PREFIX}" | grep -Eq '^v[0-9]+\.[0-9]{4}$'; then
echo "::error::version_prefix must look like vX.YYMM (got: ${VERSION_PREFIX})"
exit 1
fi
required_values="
HARBOR_ENDPOINT HARBOR_HOSTNAME HARBOR_ROBOT_ACCOUNT HARBOR_ROBOT_KEY
ADMINFRONT_URL DEVFRONT_URL ORGFRONT_URL VITE_OIDC_AUTHORITY
"
for key in ${required_values}; do
if [ -z "${!key:-}" ]; then
echo "::error::Missing required publish value: ${key}. Check Gitea repo variables/secrets."
exit 1
fi
done
- name: Compute commit-hash image tag
id: version
env:
VERSION_PREFIX: ${{ github.event.inputs.version_prefix }}
run: |
set -euo pipefail
short_sha="$(git rev-parse --short=4 HEAD)"
if ! printf '%s' "${short_sha}" | grep -Eq '^[0-9a-f]{4}$'; then
echo "::error::commit hash suffix must be 4 lowercase hexadecimal characters (got: ${short_sha})"
exit 1
fi
image_tag="${VERSION_PREFIX}.${short_sha}"
echo "image_tag=${image_tag}" >> "${GITHUB_OUTPUT}"
echo "Computed production image tag: ${image_tag}"
- name: Login to shared registry
uses: docker/login-action@v3
with:
registry: ${{ vars.HARBOR_ENDPOINT }}
username: ${{ vars.HARBOR_ROBOT_ACCOUNT }}
password: ${{ secrets.HARBOR_ROBOT_KEY }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push backend production image
uses: docker/build-push-action@v5
with:
context: ./backend
file: ./backend/Dockerfile
push: true
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/backend:${{ steps.version.outputs.image_tag }}
provenance: false
sbom: false
- name: Build and push userfront production image
uses: docker/build-push-action@v5
with:
context: .
file: ./userfront/Dockerfile
target: production
push: true
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/userfront:${{ steps.version.outputs.image_tag }}
provenance: false
sbom: false
- name: Build and push adminfront production image
uses: docker/build-push-action@v5
with:
context: .
file: ./adminfront/Dockerfile
target: production
push: true
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/adminfront:${{ steps.version.outputs.image_tag }}
build-args: |
VITE_ADMIN_PUBLIC_URL=${{ vars.ADMINFRONT_URL }}
VITE_OIDC_AUTHORITY=${{ vars.VITE_OIDC_AUTHORITY }}
VITE_OIDC_CLIENT_ID=adminfront
ORGFRONT_URL=${{ vars.ORGFRONT_URL }}
provenance: false
sbom: false
- name: Build and push devfront production image
uses: docker/build-push-action@v5
with:
context: .
file: ./devfront/Dockerfile
target: production
push: true
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/devfront:${{ steps.version.outputs.image_tag }}
build-args: |
VITE_DEVFRONT_PUBLIC_URL=${{ vars.DEVFRONT_URL }}
VITE_OIDC_AUTHORITY=${{ vars.VITE_OIDC_AUTHORITY }}
VITE_OIDC_CLIENT_ID=devfront
ORGFRONT_URL=${{ vars.ORGFRONT_URL }}
provenance: false
sbom: false
- name: Build and push orgfront production image
uses: docker/build-push-action@v5
with:
context: .
file: ./orgfront/Dockerfile
target: production
push: true
tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/orgfront:${{ steps.version.outputs.image_tag }}
build-args: |
VITE_ORGFRONT_PUBLIC_URL=${{ vars.ORGFRONT_URL }}
VITE_OIDC_AUTHORITY=${{ vars.VITE_OIDC_AUTHORITY }}
VITE_OIDC_CLIENT_ID=orgfront
provenance: false
sbom: false
- name: Upload pushed images to WORKS Drive archive
if: ${{ vars.WORKS_DRIVE_DOCKER_IMAGE_ARCHIVE_ENABLED == 'true' }}
env:
IMAGE_TAG: ${{ steps.version.outputs.image_tag }}
HARBOR_HOSTNAME: ${{ vars.HARBOR_HOSTNAME }}
WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR: ${{ vars.WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR }}
WORKS_DRIVE_TARGET: sharedrive
WORKS_DRIVE_SHARED_DRIVE_ID: ${{ vars.WORKS_DRIVE_SHARED_DRIVE_ID }}
WORKS_DRIVE_PARENT_FILE_ID: ${{ vars.WORKS_DRIVE_PARENT_FILE_ID }}
WORKS_DRIVE_OAUTH_CLIENT_ID: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_ID }}
WORKS_DRIVE_OAUTH_CLIENT_SECRET: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_SECRET }}
WORKS_DRIVE_OAUTH_CLIENT_SERVICE_ACCOUNT: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_SERVICE_ACCOUNT }}
WORKS_DRIVE_OAUTH_CLIENT_PRIVATE_KEY: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_PRIVATE_KEY }}
WORKS_DRIVE_OAUTH_REFRESH_TOKEN: ${{ secrets.WORKS_DRIVE_OAUTH_REFRESH_TOKEN }}
WORKS_ADMIN_API_BASE_URL: ${{ vars.WORKS_ADMIN_API_BASE_URL }}
WORKS_ADMIN_OAUTH_TOKEN_URL: ${{ vars.WORKS_ADMIN_OAUTH_TOKEN_URL }}
run: |
set -euo pipefail
: "${WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR:=docker-build-image}"
required_values="
IMAGE_TAG HARBOR_HOSTNAME WORKS_DRIVE_SHARED_DRIVE_ID
"
for key in ${required_values}; do
if [ -z "${!key:-}" ]; then
echo "::error::Missing required WORKS image archive value: ${key}."
exit 1
fi
done
for image in backend userfront adminfront devfront orgfront; do
image_ref="${HARBOR_HOSTNAME}/baron_sso/${image}:${IMAGE_TAG}"
docker pull "${image_ref}"
DOCKER_IMAGE_REF="${image_ref}" \
WORKS_DOCKER_IMAGE_ARCHIVE_DIR="${RUNNER_TEMP}/baron-sso-docker-image-upload" \
scripts/docker-image/upload_works_drive.sh
done

View File

@@ -0,0 +1,94 @@
name: Deploy Baron SSO Staging Images
on:
workflow_dispatch:
inputs:
image_tag:
description: "스테이징에 배포할 공용 저장소 이미지 태그 (예: v1.2606.ab12)"
required: true
type: string
jobs:
deploy-staging-images:
runs-on: ubuntu-latest
steps:
- name: Checkout deployment scripts and templates
uses: actions/checkout@v4
- name: Setup SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.STAGE_SSH_PRIVATE_KEY }}
- name: Build staging deployment bundle
env:
IMAGE_TAG: ${{ github.event.inputs.image_tag }}
IMAGE_DEPLOY_ENV: stage
IMAGE_DEPLOY_INSTANCE_NAME: ${{ vars.STAGE_INSTANCE_NAME }}
IMAGE_DEPLOY_PORT_PREFIX: ${{ vars.STAGE_PORT_PREFIX }}
IMAGE_DEPLOY_PUBLIC_URL: ${{ vars.USERFRONT_URL }}
IMAGE_DEPLOY_COMPOSE_TEMPLATE: deploy/templates/docker-compose.images.yaml
IMAGE_DEPLOY_BUNDLE_FILE: stage-image-deploy-bundle.tgz
ADMINFRONT_URL: ${{ vars.ADMINFRONT_URL }}
DEVFRONT_URL: ${{ vars.DEVFRONT_URL }}
ORGFRONT_URL: ${{ vars.ORGFRONT_URL }}
VITE_OIDC_AUTHORITY: ${{ vars.VITE_OIDC_AUTHORITY }}
IMAGE_DEPLOY_DB_PORT: ${{ vars.DB_PORT }}
IMAGE_DEPLOY_REDIS_PORT: ${{ vars.REDIS_PORT }}
IMAGE_DEPLOY_CLICKHOUSE_PORT_HTTP: ${{ vars.CLICKHOUSE_PORT_HTTP }}
IMAGE_DEPLOY_CLICKHOUSE_PORT_NATIVE: ${{ vars.CLICKHOUSE_PORT_NATIVE }}
IMAGE_DEPLOY_BACKEND_PORT: ${{ vars.BACKEND_PORT }}
IMAGE_DEPLOY_FRONTEND_PORT: ${{ vars.USERFRONT_PORT }}
ADMINFRONT_PORT: ${{ vars.ADMINFRONT_PORT }}
DEVFRONT_PORT: ${{ vars.DEVFRONT_PORT }}
ORGFRONT_PORT: ${{ vars.ORGFRONT_PORT }}
IMAGE_DEPLOY_OATHKEEPER_PROXY_PORT: ${{ vars.OATHKEEPER_PROXY_PORT }}
IMAGE_DEPLOY_DOMAIN_SUFFIX: ${{ vars.DOMAIN_SUFFIX }}
ADMINFRONT_CALLBACK_URLS: ${{ vars.ADMINFRONT_CALLBACK_URLS }}
DEVFRONT_CALLBACK_URLS: ${{ vars.DEVFRONT_CALLBACK_URLS }}
ORGFRONT_CALLBACK_URLS: ${{ vars.ORGFRONT_CALLBACK_URLS }}
HYDRA_REFRESH_TOKEN_TTL: ${{ vars.HYDRA_REFRESH_TOKEN_TTL }}
ORY_POSTGRES_USER: ${{ vars.ORY_POSTGRES_USER }}
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 }}
HYDRA_VERSION: ${{ vars.HYDRA_VERSION }}
KETO_VERSION: ${{ vars.KETO_VERSION }}
OATHKEEPER_VERSION: ${{ vars.OATHKEEPER_VERSION }}
ORY_POSTGRES_TAG: ${{ vars.ORY_POSTGRES_TAG }}
OATHKEEPER_UID: ${{ vars.OATHKEEPER_UID }}
OATHKEEPER_GID: ${{ vars.OATHKEEPER_GID }}
OATHKEEPER_INTROSPECT_CLIENT_ID: ${{ vars.OATHKEEPER_INTROSPECT_CLIENT_ID }}
ADMIN_EMAIL: ${{ vars.ADMIN_EMAIL }}
HARBOR_HOSTNAME: ${{ vars.HARBOR_HOSTNAME }}
BACKEND_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/backend
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
ORGFRONT_IMAGE_NAME: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/orgfront
IMAGE_DEPLOY_DB_PASSWORD: ${{ secrets.STG_DB_PASSWORD }}
IMAGE_DEPLOY_ORY_POSTGRES_PASSWORD: ${{ secrets.STG_ORY_POSTGRES_PASSWORD }}
IMAGE_DEPLOY_OATHKEEPER_INTROSPECT_CLIENT_SECRET: ${{ secrets.STG_OATHKEEPER_INTROSPECT_CLIENT_SECRET }}
IMAGE_DEPLOY_CLICKHOUSE_PASSWORD: ${{ secrets.CLICKHOUSE_PASSWORD }}
IMAGE_DEPLOY_COOKIE_SECRET: ${{ secrets.STG_COOKIE_SECRET }}
IMAGE_DEPLOY_JWT_SECRET: ${{ secrets.STG_JWT_SECRET }}
IMAGE_DEPLOY_CSRF_COOKIE_SECRET: ${{ secrets.STG_CSRF_COOKIE_SECRET }}
IMAGE_DEPLOY_ADMIN_PASSWORD: ${{ secrets.STG_ADMIN_PASSWORD }}
run: |
set -euo pipefail
scripts/deploy/build_image_deploy_bundle.sh
- name: Upload bundle and run requested staging image tag
env:
IMAGE_DEPLOY_BUNDLE_FILE: stage-image-deploy-bundle.tgz
DEPLOY_HOST: ${{ vars.STAGE_HOST }}
DEPLOY_USER: ${{ vars.STAGE_USER }}
DEPLOY_PATH: ${{ vars.STAGE_DEPLOY_PATH }}
HARBOR_ENDPOINT: ${{ vars.HARBOR_ENDPOINT }}
HARBOR_ROBOT_ACCOUNT: ${{ vars.HARBOR_ROBOT_ACCOUNT }}
HARBOR_ROBOT_KEY: ${{ secrets.HARBOR_ROBOT_KEY }}
run: |
set -euo pipefail
scripts/deploy/upload_and_run_image_deploy.sh