배포 Docker 이미지의 시맨틱 버전 관리 가이드 - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki

배포 Docker 이미지의 시맨틱 버전 관리 가이드

이 문서의 "버전"은 앱 코드의 버전이 아니라, 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]
Loading

dev/hotfix → main PR을 merge한 뒤, GitHub Release로 태그를 만들어야 비로소 이미지가 빌드된다.

  1. GitHub 저장소 → Releases → Draft a new release
  2. Target을 main으로 두고, Choose a tag에 v1.0.1 형식으로 입력 후 "Create new tag on publish" 선택
  3. 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 태그)에만 존재한다.

Release 따라하기

  1. 레포지토리의 Relese 들어가기
Image
  1. Create new releases 클릭
Image
  1. release 생성
Image

3-1. 버전 작성

새 버전은 git tag를 새로 만들어서 작성합니다. "v0.0.0" 형식으로 작성합니다. 이전 버전 태그를 선택할 수 있습니다.

Image Image

3-2. Release 할 브랜치 선택

저희 팀은 main의 내용물만 배포하므로 main으로 선택합니다. (지금은 테스트 상 dev로 선택했습니다.)

Image

3-3. Release 내용 작성 (선택)

Image

변경 사항을 작성할 수 있습니다. Generate release note를 누르면 이전까지의 작업 내용을 가져옵니다.

Image

3-3. publish release

Image
  1. 이후 Github Actions가 이미지를 빌드하고 GHCR에 배포합니다.
Image Image Image
⚠️ **GitHub.com Fallback** ⚠️