1
0
forked from baron/baron-sso
Files
baron-sso/docs/works-drive-docker-image-archive.md

8.4 KiB

WORKS Drive Docker Image Archive

목적

WORKS Drive는 Docker Registry HTTP API v2 backend로 직접 사용하지 않는다. 대신 프로덕션 배포용 Docker 이미지를 docker save 결과물로 내보내고, zstd 압축 archive와 검증 파일을 WORKS Shared Drive에 보관하는 CLI 기반 보조 저장소로 사용한다.

이 방식은 다음 상황을 목표로 한다.

  • Harbor 또는 공용 Registry 장애 시 수동 복구용 이미지 보관
  • 작은 규모의 프로덕션 배포 이미지 이관
  • docker load 기반 오프라인 배포

Harbor는 이 흐름의 1차 이미지 저장소다. Gitea Actions의 publish workflow가 reg.hmac.kr/baron_sso/<service>:<image_tag> 형태로 이미지를 push하고, staging/production deploy workflow는 같은 image tag를 Harbor에서 pull한다. WORKS Drive는 같은 이미지를 별도로 보관하는 복구용 archive이며, staging/prod가 평상시에 직접 pull하는 대상이 아니다.

현재 Gitea Actions 설정 상태

2026-06-19 기준 repo Actions 설정에서 Harbor 변수/시크릿은 등록되어 있다.

  • HARBOR_ENDPOINT=https://reg.hmac.kr
  • HARBOR_HOSTNAME=reg.hmac.kr
  • HARBOR_ROBOT_ACCOUNT=robot$namecard_sso
  • secret HARBOR_ROBOT_KEY

Docker image archive 업로드 단계는 .gitea/workflows/production_image_publish.ymlUpload pushed images to WORKS Drive archive step에서 실행된다. 단, 이 step은 다음 조건을 만족할 때만 실행된다.

if: ${{ vars.WORKS_DRIVE_DOCKER_IMAGE_ARCHIVE_ENABLED == 'true' }}

현재 repo Actions 설정에는 Docker image archive용 WORKS Drive 변수/시크릿이 등록되어 있지 않다. 업로드를 켜려면 최소한 다음 값을 등록해야 한다.

  • variable WORKS_DRIVE_DOCKER_IMAGE_ARCHIVE_ENABLED=true
  • variable WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR=docker-build-image
  • variable WORKS_DRIVE_SHARED_DRIVE_ID
  • 선택 variable WORKS_DRIVE_PARENT_FILE_ID
  • secret WORKS_DRIVE_OAUTH_CLIENT_ID
  • secret WORKS_DRIVE_OAUTH_CLIENT_SECRET
  • secret WORKS_DRIVE_OAUTH_CLIENT_SERVICE_ACCOUNT
  • secret WORKS_DRIVE_OAUTH_CLIENT_PRIVATE_KEY
  • refresh token 방식을 쓸 경우 secret WORKS_DRIVE_OAUTH_REFRESH_TOKEN

저장 구조

기본 최상위 디렉터리는 다음 환경 변수로 지정한다.

WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR=docker-build-image

이미지는 WORKS Shared Drive에서 다음 구조로 저장한다.

docker-build-image/<repository-path>/<tag>/
  image.tar.zst
  image.tar.zst.sha256
  manifest.json

예시:

docker-build-image/baron_sso/backend/v1.2606.ab12/
  image.tar.zst
  image.tar.zst.sha256
  manifest.json

Registry hostname은 저장 경로에서 제외한다. 예를 들어 registry.example/baron_sso/backend:v1.2606.ab12baron_sso/backend/v1.2606.ab12 아래에 저장한다.

Manifest

manifest.json에는 다음 정보를 기록한다.

  • archive format: docker-save-zstd
  • 원본 image_ref
  • repository path
  • tag
  • Docker image id
  • Git commit
  • archive 파일명, 크기, sha256
  • WORKS Drive remote path
  • 복원 명령 예시

복원은 다음 흐름으로 처리한다.

sha256sum -c image.tar.zst.sha256
zstd -d -c image.tar.zst | docker load

업로드 CLI

로컬 컨테이너를 먼저 이미지로 commit한 뒤 업로드하려면 다음처럼 실행한다.

WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR=docker-build-image \
WORKS_DOCKER_COMMIT_CONTAINER=baron_backend \
DOCKER_IMAGE_REF=registry.example/baron_sso/backend:v1.2606.ab12 \
scripts/docker-image/upload_works_drive.sh

이미지가 이미 로컬에 있으면 WORKS_DOCKER_COMMIT_CONTAINER를 생략한다.

DOCKER_IMAGE_REF=registry.example/baron_sso/backend:v1.2606.ab12 \
scripts/docker-image/upload_works_drive.sh

실제 업로드에는 기존 백업 업로드와 같은 WORKS Drive 인증 변수를 사용한다.

  • WORKS_DRIVE_TARGET=sharedrive
  • WORKS_DRIVE_SHARED_DRIVE_ID 또는 WORKS_SHAREDRIVE_ID
  • 선택: WORKS_DRIVE_PARENT_FILE_ID
  • WORKS_DRIVE_ACCESS_TOKEN, WORKS_DRIVE_ACCESS_TOKEN_FILE, WORKS_DRIVE_ACCESS_TOKEN_CMD, WORKS_DRIVE_OAUTH_REFRESH_TOKEN, 또는 서비스 계정 OAuth 변수

업로드 전 packaging만 확인하려면 다음을 사용한다.

WORKS_DRIVE_DRY_RUN=true \
DOCKER_IMAGE_REF=registry.example/baron_sso/backend:v1.2606.ab12 \
scripts/docker-image/upload_works_drive.sh

dry-run도 실제 docker save, zstd, checksum, manifest 생성을 수행한다. WORKS Drive API 호출만 생략하므로 업로드 전 산출물 검증에 사용할 수 있다.

다운로드 및 복원 검증 CLI

WORKS Drive에서 다음 세 파일을 같은 로컬 디렉터리로 내려받은 뒤 검증한다.

image.tar.zst
image.tar.zst.sha256
manifest.json

checksum, manifest, zstd stream 무결성만 확인하려면 다음을 실행한다.

scripts/docker-image/verify_archive.sh /path/to/downloaded/archive

make 타깃을 사용할 수도 있다.

make docker-image-verify-works \
  WORKS_DOCKER_IMAGE_ARCHIVE_DIR=/path/to/downloaded/archive

실제 Docker image load까지 검증하려면 다음을 실행한다.

WORKS_DOCKER_VERIFY_LOAD=true \
scripts/docker-image/verify_archive.sh /path/to/downloaded/archive

검증은 다음 조건을 모두 확인한다.

  • image.tar.zst.sha256 checksum 성공
  • manifest.jsonschema_version=1, format=docker-save-zstd
  • manifest의 archive 파일명, sha256, size와 실제 파일 일치
  • zstd -t 무결성 성공
  • 선택적으로 docker load 성공

현재 repo에는 WORKS Drive API에서 파일을 자동 다운로드하는 CLI는 없다. 따라서 자동 다운로드 스크립트를 만들기 전까지는 WORKS Drive UI 또는 운영자가 승인한 API 도구로 세 파일을 내려받고, 위 검증 CLI로 복원 가능성을 확인한다.

API로 다운로드할 때는 대상 archive 폴더의 children을 조회해 각 파일의 fileId를 얻은 뒤 다음 endpoint를 호출한다.

GET /v1.0/sharedrives/<sharedDriveId>/files/<fileId>/download

검증 결과 이 endpoint는 302 Location을 반환한다. curl -L만 사용하면 리다이렉트 대상 요청에 인증 헤더가 유지되지 않아 UNAUTHORIZED JSON이 파일로 저장될 수 있다. 자동화할 때는 리다이렉트 대상에도 인증 헤더를 유지하도록 처리해야 한다. curl 기준으로는 다음 형태를 사용한다.

curl -sS -L --location-trusted \
  -H "Authorization: Bearer <access-token>" \
  -o image.tar.zst \
  "https://www.worksapis.com/v1.0/sharedrives/<sharedDriveId>/files/<fileId>/download"

smoke 검증에는 Alpine 계열보다 운영 환경과 libc/패키지 계열 차이가 적은 Debian slim 계열을 사용한다.

docker create --name baron-works-image-smoke debian:trixie-slim \
  sh -c 'printf works-drive-docker-image-smoke >/works-smoke.txt'
docker start -a baron-works-image-smoke
WORKS_DOCKER_COMMIT_CONTAINER=baron-works-image-smoke \
DOCKER_IMAGE_REF=registry.example/baron_sso/works-smoke:works-test-ab12 \
scripts/docker-image/upload_works_drive.sh

로컬 smoke 검증 예시는 다음과 같다.

WORKS_DRIVE_DRY_RUN=true \
WORKS_DOCKER_IMAGE_ARCHIVE_DIR=/tmp/baron-sso-works-verify-smoke \
DOCKER_IMAGE_REF=alpine:latest \
scripts/docker-image/upload_works_drive.sh

scripts/docker-image/verify_archive.sh \
  /tmp/baron-sso-works-verify-smoke/alpine/latest

WORKS_DOCKER_VERIFY_LOAD=true \
scripts/docker-image/verify_archive.sh \
  /tmp/baron-sso-works-verify-smoke/alpine/latest

Staging/Production 계약

Action에서 dev 브랜치를 checkout한 뒤 한 번만 이미지를 빌드하고 immutable image_tag를 계산한다. staging과 production은 같은 image_tag를 입력받아 같은 registry image를 pull한다.

dev branch -> publish image tag vX.YYMM.<commit4> -> staging deploy -> production deploy

WORKS Drive archive도 Action에서 push된 이미지를 다시 pull한 뒤 docker save로 만든다. 따라서 WORKS archive, staging, production은 모두 같은 registry image tag를 기준으로 한다.

제한

  • 이 구조는 docker push/docker pull과 호환되는 Registry backend가 아니다.
  • layer deduplication이 없으므로 같은 기반 이미지가 반복 저장된다.
  • 배포 전에는 반드시 image.tar.zst.sha256 검증 후 docker load를 수행해야 한다.
  • tag 없는 image ref와 digest-only image ref는 지원하지 않는다.