GitLab Release Metadata Spec (운영 기준)¶
0. 전제¶
pull 기반 상태 수렴 배포 구조에서 운영 서버가 참조하는 release metadata 규격을 정의함.
본 문서의 대상:
- Build Runner
- 운영 서버 polling 스크립트
- 배포 완료 / 실패 리포트 로직
1. 목적¶
release metadata는 운영 서버가 다음을 판단하기 위한 기준 파일임.
- 새로운 배포 버전 존재 여부
- 다운로드 대상 패키지
- 배포 수행 순서
- 현재 선언된 목표 상태
운영 기준:
- CI/CD는 release metadata를 갱신함
- 운영 서버는 metadata를 polling 하여 현재 상태와 비교함
- 운영 서버는 metadata 기준으로 self-pull 배포를 수행함
- release metadata는 실제 배포 실행 스크립트가 아니라 상태 선언(state declaration) 파일임
- 운영 서버는 release metadata 기준으로 목표 상태(desired state)를 판단함
- CI/CD는 release metadata publish만 수행함
- 운영 서버는 현재 상태(current state)를 desired state로 수렴(reconciliation)시킴
- release metadata 구조 변경 시 운영 서버와 함께 버전 관리함
2. 파일명 및 위치¶
환경별 metadata 파일을 분리하여 관리함.
일반 구조:
{SERVICE_PREFIX}/{SERVICE_NAME}/{RELEASE_ENV}/current/{RELEASE_ENV}.json
{SERVICE_PREFIX}/{SERVICE_NAME}/{RELEASE_ENV}/releases/{RELEASE_ENV}-{PACKAGE_VERSION}.json
운영 기준:
{RELEASE_ENV}는 Release Yaml 파일 (.ops/ci/release-branch-versions/{CI_COMMIT_BRANCH}.yaml) 에 대응하는 branch/env 이름임- 운영 서버는 자신이 속한 environment metadata만 polling 함
3. Release State 선언 구조¶
- Release Yaml 파일
- CI/CD는 브랜치 기준 단일 target 환경만 처리함.
- release 대상 환경은 다음 구조를 사용하여 선언함.
- 브랜치명과 release 선언 파일명은 동일해야 함
- 현재 pipeline은 현재 브랜치와 동일한 release 선언 파일만 처리함
- 하나의 pipeline은 하나의 target environment만 처리함
- 다른 Release Yaml 파일 변경은 무시함
- Release Yaml 파일 이 없는 branch 는 release target 이 아님
.ops/ci/release-branch-versions/
├── pre-production.yaml
├── production.yaml
└── {release-target-branch}.yaml
예:
| 브랜치 | 처리 대상 |
|---|---|
| pre-production | pre-production.yaml |
| production | production.yaml |
| ko-dev-test | ko-dev-test.yaml |
4. 표준 구조¶
- Release metadata 는 운영 서버가 현재 배포 대상 Release 를 판단하기 위한 기준 파일임.
- 운영 서버는
current/{RELEASE_ENV}.json만 polling 하며, metadata 안에 선언된releases경로의 package 를 다운로드함. - 운영 서버는
releases경로를 직접 탐색(list)하지 않음. - 운영 서버는 GitLab Generic Package Registry 를 직접 사용하지 않음.
- GitLab Generic Package Registry 는 CI 내부 immutable artifact 보관 및 release publish 검증 기준으로 사용함.
- 실제 운영 배포 기준 source of truth 는 Release Storage 의
current/{RELEASE_ENV}.json및 releases 경로임.
4.1 실제 운영 Metadata 예시¶
{
"target_env": "production",
"project_name": "streaum",
"service_prefix": "frontend",
"service_name": "streaum.com",
"declared_version": "1.2.1",
"package_version": "20260515-081145-1.2.1-3f1dcc3a",
"release_storage": {
"type": "release-storage",
"endpoint": "https://release.sncompany.com",
"region": "ap-northeast-2",
"bucket": "streaum",
"base_prefix": "frontend/streaum.com/production",
"release_prefix": "frontend/streaum.com/production/releases",
"current_prefix": "frontend/streaum.com/production/current",
"metadata_path": "frontend/streaum.com/production/releases/production-20260515-081145-1.2.1-3f1dcc3a.json",
"current_metadata_path": "frontend/streaum.com/production/current/production.json"
},
"metadata_name": "production-20260515-081145-1.2.1-3f1dcc3a.json",
"metadata_path": "frontend/streaum.com/production/releases/production-20260515-081145-1.2.1-3f1dcc3a.json",
"current_metadata_name": "production.json",
"current_metadata_path": "frontend/streaum.com/production/current/production.json",
"package_name": "streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz",
"package_path": "frontend/streaum.com/production/releases/streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz",
"package_sha256_name": "streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz.sha256",
"package_sha256_path": "frontend/streaum.com/production/releases/streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz.sha256",
"package_sha256": "c180777147eb1ed191bd4d62230529cabea858bea55f946364af0767b7a13660",
"package_size_bytes": 148961479,
"package_size_mb": 142.06,
"commit_sha": "3f1dcc3afdc6b328fa6fa1d22330b3b980635bd1",
"commit_short_sha": "3f1dcc3a",
"pipeline_id": "137",
"steps": [
"download",
"verify",
"extract",
"activate",
"report"
],
"source": {
"gitlab_package_registry": {
"package_registry_name": "streaum.com-production",
"package_registry_base_url": "https://gitlab.sncompany.com/api/v4/projects/1/packages/generic/streaum.com-production/20260515-081145-1.2.1-3f1dcc3a",
"package_upload_url": "https://gitlab.sncompany.com/api/v4/projects/1/packages/generic/streaum.com-production/20260515-081145-1.2.1-3f1dcc3a/streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz",
"package_sha256_upload_url": "https://gitlab.sncompany.com/api/v4/projects/1/packages/generic/streaum.com-production/20260515-081145-1.2.1-3f1dcc3a/streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz.sha256"
},
"package_name": "streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz",
"package_path": ".artifacts/production/packages/streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz",
"package_sha256_name": "streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz.sha256",
"package_sha256_path": ".artifacts/production/packages/streaum.com-production-20260515-081145-1.2.1-3f1dcc3a.tar.gz.sha256"
},
"updated_at": "2026-05-15T08:15:37Z"
}
운영 기준:
current/{RELEASE_ENV}.json은 운영 서버가 polling 하는 Release Pointer 임package_path는 운영 서버가 다운로드할 tar.gz object path 임package_sha256_path는 Release Storage 에 저장된 sha256 checksum file object path 이며, 감사/추적/수동 검증 용도로 사용함- 운영 서버는
current/{RELEASE_ENV}.json만 polling 함 - 운영 서버는 metadata 안에 선언된
releasespath 를 사용하여 package download 수행 - 운영 서버는
releases경로를 직접 탐색(list)하지 않음 package_version변경을 기준으로 신규 배포 여부를 판단함steps는 운영 서버 deploy agent 의 실행 단계를 정의함releases경로의 Object 는 immutable release archive 로 취급함current/{RELEASE_ENV}.json만 overwrite 허용- 운영 서버는
source.gitlab_package_registry값을 배포에 사용하지 않음 source는 CI 산출물 추적, 감사, 장애 분석 용도로만 사용함- 운영 서버의 실제 package 다운로드 기준은
package_path임 - 운영 서버의 sha256 검증 기준은 metadata 내부의
package_sha256값임 package_sha256_path는 Release Storage 에 저장된 checksum file object path 이며, 감사/추적/수동 검증 용도로 사용함- 현재
poll-release.sh는package_sha256_path를 별도로 다운로드하지 않음 package_sha256_path는 CI publish 결과 추적 및 수동 검증용 metadata 로 유지함
5. 필드 정의¶
| 필드명 | 설명 | 필수 |
|---|---|---|
| target_env | 대상 환경명 | O |
| project_name | 최상위 제품/서비스 단위. GitLab 최상위 Group 및 Release Storage Bucket 기준 | O |
| service_prefix | PROJECT_NAME 하위 서비스 분류 경로. 예: frontend, backend, infra |
O |
| service_name | 실제 실행/배포 대상 서비스명. GitLab Project 이름 및 runtime app name 기준 | O |
| declared_version | release 선언 버전 | O |
| package_version | immutable package version | O |
| release_storage | Release Storage 정보 | O |
| release_storage.type | Release Storage 타입 | O |
| release_storage.endpoint | Release Storage Endpoint | O |
| release_storage.region | Release Storage region 값 | O |
| release_storage.bucket | Release Storage Bucket 명 | O |
| release_storage.base_prefix | {SERVICE_PREFIX}/{SERVICE_NAME}/{RELEASE_ENV} 기준 base object prefix |
O |
| release_storage.release_prefix | immutable release object 저장 prefix | O |
| release_storage.current_prefix | current metadata 저장 prefix | O |
| release_storage.metadata_path | versioned release metadata object path | O |
| release_storage.current_metadata_path | current release metadata object path | O |
| metadata_name | versioned release metadata 파일명 | O |
| metadata_path | versioned release metadata object path | O |
| current_metadata_name | current release metadata 파일명 | O |
| current_metadata_path | current release metadata object path | O |
| package_name | release package 파일명 | O |
| package_path | release package object path | O |
| package_sha256_name | sha256 파일명 | O |
| package_sha256_path | sha256 object path | O |
| package_sha256 | sha256 checksum | O |
| package_size_bytes | package size(byte) | O |
| package_size_mb | package size(MB) | O |
| commit_sha | 대상 commit sha | O |
| commit_short_sha | short commit sha | O |
| pipeline_id | GitLab pipeline id | O |
| steps | 운영 서버가 수행할 배포 단계 | O |
| source | CI 산출물 원본 정보 | O |
| source.gitlab_package_registry | GitLab Generic Package Registry 업로드 정보 | O |
| source.gitlab_package_registry.package_registry_name | GitLab Generic Package Registry package 명 | O |
| source.gitlab_package_registry.package_registry_base_url | GitLab Generic Package Registry base URL | O |
| source.gitlab_package_registry.package_upload_url | GitLab Generic Package Registry package upload URL | O |
| source.gitlab_package_registry.package_sha256_upload_url | GitLab Generic Package Registry sha256 upload URL | O |
| source.package_name | CI 내부 package artifact 파일명 | O |
| source.package_path | Runner 내부 package artifact 상대 경로 | O |
| source.package_sha256_name | CI 내부 sha256 파일명 | O |
| source.package_sha256_path | CI 내부 sha256 파일 경로 | O |
| updated_at | release metadata publish 시각(UTC) | O |
운영 기준:
- 운영 서버는
package_version기준으로 신규 배포 여부 판단함 - steps는 선언된 순서를 그대로 수행함
- metadata 구조 변경 시 운영 서버와 함께 버전 관리함
- 운영 서버는 current metadata만 polling 함
- 운영 서버는 metadata 안에 선언된 releases path 를 기준으로 package download 수행함
6. steps 규칙¶
steps는 release metadata 의 배포 의도와 감사 추적을 위한 단계 목록임.- 현재
poll-release.sh는 metadata 의steps값을 동적으로 해석하여 실행하지 않음 - 실제 실행 순서는
poll-release.sh내부 고정 흐름을 따름 steps는 release metadata 감사, 문서화, 향후 agent 확장 용도로 유지함- 신규 step 을 실제 runtime 동작으로 반영하려면 운영 서버
poll-release.sh수정이 필요함 - verify 단계 의미는 package sha256 검증을 포함함
- verify 실패 시 activate 수행 금지 원칙은 유지함
허용 단계 예시:
download
verify
extract
activate
report
7. update-release.sh 역할¶
- CI/CD는 update-release.sh를 통해 release metadata 를 publish 함.
역할:
- release package publish
- release sha256 publish
- versioned release metadata publish
- current metadata publish
- immutable release archive publish
- current release state publish
운영 기준:
- CI/CD는 운영 서버에 직접 배포하지 않음
- update-release.sh 는 Release Storage 에 release state 만 publish 함
- CI/CD는 운영 서버 접근 권한을 가지지 않음
- set_release_state 단계는 remote execute 단계가 아니라 release state publication 단계임
- 운영 서버는 current metadata polling 후 직접 배포 수행함
publish 순서:
1. releases 경로에 versioned tar.gz publish
2. releases 경로에 versioned sha256 publish
3. releases 경로에 versioned metadata publish
4. current/{RELEASE_ENV}.json 마지막 publish
운영 기준:
- current metadata 는 반드시 마지막에 publish 함
- 운영 서버는 current metadata 변경을 기준으로 deploy 수행
- current 경로에는 tar.gz / sha256 저장 금지
- tar.gz / sha256 은 releases 경로에만 저장함
8. Release Metadata CI/CD Variables¶
- set_release_state 단계는 Release Storage publish 를 위해 다음 GitLab CI/CD Variables 를 사용함.
| Variable | 설명 |
|---|---|
| MINIO_ENDPOINT | S3 API Endpoint |
| MINIO_REGION | AWS S3 확장을 위한 변수 |
| MINIO_BUCKET | Release Storage Bucket |
| MINIO_ACCESS_KEY | CI publish Access Key |
| MINIO_SECRET_KEY | CI publish Secret Key |
| MINIO_SERVICE_PREFIX | Release Storage Object Prefix. 예: {SERVICE_PREFIX}/{SERVICE_NAME} |
예:
MINIO_ENDPOINT="https://release.example.com"
MINIO_REGION="ap-northeast-2" # AWS S3 확장을 위한 변수
MINIO_BUCKET={PROJECT_NAME}
MINIO_ACCESS_KEY=xxxxxxxx
MINIO_SECRET_KEY=xxxxxxxx
MINIO_SERVICE_PREFIX={SERVICE_PREFIX}/{SERVICE_NAME}
운영 기준:
- set_release_state stage 만 해당 변수 접근 허용
- MINIO_SECRET_KEY 는 최소 권한 원칙 적용
- 운영 서버에는 write 권한 제공 금지
- publish 권한은 CI/CD 전용으로 분리 관리함
- 가능하면 전용 CI Publisher 계정 사용
- production / pre-production branch 는 Protected Branch 권장
- Protected Variable 을 사용하는 경우 release target branch 는 Protected Branch 로 등록해야 함
- release target branch 는
.ops/ci/release-branch-versions/{branch}.yaml존재 여부로 결정함 - 예:
pre-production,production,ko-dev-test
8.1 GitLab CI/CD Variables 설정¶
경로:
Project → Settings → CI/CD → Variables
변수 생성:
| Key | 권장 값 예시 |
|---|---|
| MINIO_ENDPOINT | S3 API Endpoint |
| MINIO_REGION | AWS S3 확장을 위한 변수 |
| MINIO_BUCKET | {PROJECT_NAME} |
| MINIO_ACCESS_KEY | xxxxxxxx |
| MINIO_SECRET_KEY | xxxxxxxx |
| MINIO_SERVICE_PREFIX | {SERVICE_PREFIX}/{SERVICE_NAME} |
운영 기준:
- MINIO_SECRET_KEY 는 Masked + Protected 설정 권장
- MINIO_ACCESS_KEY 는 Protected 설정 권장
- production / pre-production branch 는 Protected Branch 권장
- release target branch 는 Protected Branch 사용 권장
- Protected Variable 을 사용하는 경우 release target branch 는 반드시 Protected Branch 로 등록해야 함
- feature branch 및 일반 사용자 pipeline 에서는 release publish 금지
8.2 Release Storage 권한 기준¶
권장 권한:
| 항목 | 권장 |
|---|---|
| CI/CD 권한 | releases publish + current publish |
| 운영 서버 권한 | current read + releases read |
| 운영 서버 쓰기 | 금지 |
| Delete 권한 | 별도 maintainer 계정 분리 |
운영 기준:
- 운영 서버에 write 권한 제공 금지
.gitlab-ci.yml에 Access Key 하드코딩 금지- 개인 관리자 계정 장기 사용 금지
- CI publish 계정과 운영 서버 계정 분리
- current metadata 만 overwrite 허용
- releases Object overwrite 금지
9. 운영 서버 동작 기준¶
운영 서버는 다음 순서로 동작함:
1. current/{RELEASE_ENV}.json polling
2. 현재 package_version 과 metadata.package_version 비교
3. metadata.package_path download
4. metadata.package_sha256 값 기준 sha256 verify
5. tar safety verify
6. extract / stage / promote
7. after-prepare hook 실행
8. current symlink activate
9. PM2 delete/start/save
10. current-release-state.json 갱신
11. cleanup
12. final verify
운영 기준:
- deploy lock 사용
- local deployed-state 유지
- verify 실패 시 activate 금지
- 운영 서버는 GitLab 접근 금지
- 운영 서버는 current metadata 변경을 기준으로 상태 수렴 수행
- 운영 서버는 metadata 안에 선언된 releases path 만 사용
- 현재
poll-release.sh는package_sha256_path를 별도로 다운로드하지 않음 - 현재
poll-release.sh는 metadata 내부의package_sha256값으로 package file 을 검증함
10. Detect 단계 연계¶
운영 기준:
- CI/CD는 Detect 단계 결과를 기반으로 release-state publish 수행 여부를 결정함
- release target 여부는 Release Yaml 파일 존재 여부로 판단함
- 해당 Release Yaml 파일 이 없으면
TARGET_CHANGED=false로 처리함 Web(New Pipeline)은 Release Yaml 파일이 있는 branch 에서 수동 release 실행 요청으로 처리함pushpipeline 은 Release Yaml 파일이 있는 branch 에서 commit 반영 release 로 처리함- Detect 단계는 현재 브랜치와 동일한 release 선언 파일만 처리함
- 하나의 pipeline은 하나의 target environment만 처리함
- Detect 결과는 downstream stage summary 출력에 사용될 수 있음
TARGET_CHANGED 기준:
| 조건 | TARGET_CHANGED | TARGET_CHANGE_REASON |
|---|---|---|
| release yaml 없음 | false |
not_release_target |
Web(New Pipeline) + release yaml 있음 |
true |
manual_web_pipeline |
push + release yaml 있음 + target yaml 변경됨 |
true |
declared_version_changed |
push + release yaml 있음 + target yaml 변경 없음 |
true |
commit_sha_changed |
| 기타 pipeline source | false |
unsupported_pipeline_source |
11. 동시 실행 및 상태 충돌 방지¶
release metadata 는 environment 별 단일 current metadata 파일로 관리됨.
운영 기준:
- 동일 environment current metadata 는 동시에 갱신하지 않음
- set_release_state Job 은 GitLab
resource_group사용을 강하게 권장함 - 동일 TARGET_ENV_NAME 에 대한 pipeline 은
직렬화(serialization)하여 처리함 - current metadata 는 마지막에 publish 함
- 운영 서버는 current metadata 변경을 기준으로 신규 release 감지 수행
- releases 경로의 Object 는 immutable archive 로 취급
- 동일 releases Object overwrite 금지
예:
resource_group: "release-state-${CI_COMMIT_BRANCH}"
12. 금지 사항¶
- latest 문자열을 실제 배포 버전으로 사용 금지
- 환경 혼합 metadata 사용 금지
- metadata 수동 수정 금지
- 운영 서버가 metadata 없이 임의 배포 수행 금지
13. 결론¶
- release metadata는 배포 실행이 아닌 상태 선언 파일임
- CI/CD는 metadata를 갱신함
- 운영 서버는 metadata를 기준으로 배포 수행함
배포는 중앙에서 push하지 않음.
운영 서버가 상태를 확인하고 직접 수행하는
pull 기반 상태 수렴 구조를 따름