배포 Docker 이미지의 시맨틱 버전 관리 가이드 - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki
이 문서의 "버전"은 앱 코드의 버전이 아니라, main에 배포할 때 GHCR에 올라가는 Docker 이미지 태그(예: 1.0.1)를 말한다. FE/BE/AI 개발자가 dev → main 배포를 준비할 때 참고하는 문서이다.
운영(main) 배포 이미지의 버전은 Git tag로 관리한다. main에 배포할 커밋에 v1.0.1 형식의 태그를 붙이고 push하면, 그 태그가 Docker 이미지를 빌드해 GHCR에 올리는 트리거가 된다.
2단계. CI(지속적 통합) 파이프라인 설계의 "Docker Image 관리 전략"에서 정해둔 규칙이다.
- 배포 이미지(main): Semantic Version(
MAJOR.MINOR.PATCH, 예:1.0.1)만 태그로 사용 - dev 이미지(dev push):
dev-<commit SHA>, 최신 버전은latest
Semantic Version 정의
MAJOR.MINOR.PATCH
| 구분 | 기준 | 예시 |
|---|---|---|
| MAJOR | 기존 API와 호환되지 않는 변경 | 응답 필드 삭제, 엔드포인트 경로/이름 변경 |
| MINOR | 기존 API와 호환되면서 새 기능 추가 | 새 엔드포인트 추가, 선택적 파라미터 추가 |
| PATCH | API/기능 변화 없는 사소한 수정 | 버그 수정, 오타 수정, 응답 속도 개선 |
Semantic Version(MAJOR.MINOR.PATCH, 예: 1.0.1)은 배포마다 세 자리 중 단 하나만 올린다.
| 상황 | 올리는 자리 | 예시 |
|---|---|---|
| hotfix → main (긴급 배포) | 항상 PATCH |
1.0.0 → 1.0.1
|
| dev → main (배포가능 버전 push) | 그 주 dev에 쌓인 변경 중 가장 영향도 높은 등급 (MAJOR > MINOR > PATCH 순) | API 호환성 깨렸으면 MAJOR, 새 기능 추가면 MINOR, 버그 수정만 있으면 PATCH |
이 판단은 CI가 자동으로 하지 않고, PR을 merge하고 Release를 만드는 사람이 직접 정해야 한다.
| 브랜치 | 트리거 | 이미지 태그 | 버전 출처 |
|---|---|---|---|
dev |
dev push(merge) |
latest, dev-<short SHA>
|
없음 |
main |
release 태그(v*.*.*) push |
Semantic Version (예: 1.0.1) |
Git tag (예: v1.0.1) |
main은 태그를 push해야만 배포 이미지가 만들어진다. dev/hotfix 변경사항을 main에 PR로 merge하는 것만으로는 이미지가 빌드되지 않는다.
flowchart LR
A[dev/hotfix -> main PR merge] -->|태그 없으면 여기서 멈춤| B[main에 커밋만 있음]
B --> C[GitHub Release 생성
태그 v1.0.1]
C -->|tag push| D[fe/ai/be-docker-publish 실행]
D --> E[GHCR에 1.0.1 이미지 push]
dev/hotfix → main PR을 merge한 뒤, GitHub Release로 태그를 만들어야 비로소 이미지가 빌드된다.
- GitHub 저장소 → Releases → Draft a new release
-
Target을
main으로 두고, Choose a tag에v1.0.1형식으로 입력 후 "Create new tag on publish" 선택 - Publish release 클릭
이 클릭 한 번이 git tag v1.0.1 && git push origin v1.0.1과 동일한 효과를 낸다(GitHub이 대신 태그를 만들고 push함). GitHub Release 쪽이 브라우저에서 끝나고 릴리즈 노트도 남으니 이 방법을 권장한다.
Q. 태그는 v1.0.1인데 이미지 태그에는 왜 v가 빠지나요?
Git/GitHub은 버전 태그에 v를 붙이는 게 관례이고(v1.0.1), Docker 이미지 태그는 접두어 없이 숫자만 쓰는 게 관례다(예: python:3.13.13). docker/metadata-action의 type=semver,pattern={{version}}이 이 둘의 차이를 자동으로 맞춰준다.
Q. main에 PR을 merge만 했는데 왜 이미지가 안 만들어지나요?
의도된 동작이다. 트리거가 "main push"가 아니라 "release 태그(v*.*.*) push"로 바뀌어서, merge하는 시점과 배포용 이미지를 만드는 시점(태그를 붙이는 시점)이 의도적으로 분리되어 있다. 위 "배포 절차"대로 태그를 따로 만들어야 한다.
Q. dev에도 태그를 달아야 하나요?
아니오. dev는 기존처럼 dev 브랜치에 push하기만 하면 latest와 dev-<short SHA> 태그가 자동으로 붙는다. 시맨틱 버전은 main(release 태그)에만 존재한다.
- 레포지토리의 Relese 들어가기
- Create new releases 클릭
- release 생성
3-1. 버전 작성
새 버전은 git tag를 새로 만들어서 작성합니다. "v0.0.0" 형식으로 작성합니다. 이전 버전 태그를 선택할 수 있습니다.
3-2. Release 할 브랜치 선택
저희 팀은 main의 내용물만 배포하므로 main으로 선택합니다. (지금은 테스트 상 dev로 선택했습니다.)
3-3. Release 내용 작성 (선택)
변경 사항을 작성할 수 있습니다. Generate release note를 누르면 이전까지의 작업 내용을 가져옵니다.
3-3. publish release
- 이후 Github Actions가 이미지를 빌드하고 GHCR에 배포합니다.