빌드, 릴리스, 실행

핵심 인사이트 (3줄 요약)

  1. 본질: 빌드, 릴리스, 실행 원칙은 코드를 프로덕션에 배포하는 과정을 세 개의 엄격히 분리된 단계로 나누어야 한다는 12팩터 앱의 제5원칙이다. 빌드 단계에서 소스코드를 실행 가능한 바이너리로 변환하고, 릴리스 단계에서 설정과 결합하여 배포 가능한 패키지를 생성하며, 실행 단계에서 그 패키지를 런타임에서 실행한다.
  2. 가치: 이 세 단계를 분리하면 롤백이 특정 단계로 한정되어 신속 정확해지고, 각 단계의 책임이 명확해져 운영 효율성과 시스템 안정성이 향상된다.
  3. 융합: CI/CD 파이프라인에서 이 원칙은 명시적 단계 분리로 구현되고, GitOps에서는 빌드/릴리스/실행이 자동화된 파이프라인으로 연결된다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

소프트웨어 배포 프로세스는 본질적으로 세 가지 핵심 활동으로 구성된다. 첫째, 소스코드를 실행 가능한 산출물로 변환하는 활동(빌드)이고, 둘째, 그 산출물에 환경별 설정을 부여하여 배포 가능한 패키지로 완성하는 활동(릴리스)이며, 셋째, 그 패키지를 실제 런타임 환경에서 실행하는 활동(실행)이다.

전통적인 방식에서는 이 단계들이 혼재되는 경우가 많았다. 빌드 스크립트 내에서 설정을 직접 하드코딩하거나, 실행 단계에서 갑자기 소스코드를 수정하거나, 빌드 산출물에 설정이 포함되어 환경 간 차이가 발생等现象이 그것이다. 이러한 혼재는 다음과 같은 문제를 야기한다:

  • 추적 불가능성: 어떤 버전의 코드가 어떤 설정과 함께 배포되었는지 알 수 없다.
  • 롤백의 어려움: 문제가 발생했을 때 이전 상태로 돌아가려면 여러 요소를 동시에 원복해야 한다.
  • 재현성의 부재: 동일 환경에서의 재배포가 보장되지 않는다.

12팩터 앱의 빌드, 릴리스, 실행 원칙은 이 세 단계를 엄격히 분리하고 각각을 독립적으로 관리할 것을 요구한다. 이렇게 하면 문제는"빌드에러 → 빌드만 다시, 설정오류 → 릴리스만 다시"로 특정할 수 있어 수정이 용이하다.

아래 다이어그램은 전통적 혼재 방식과 세 단계 분리의 차이를 보여준다.

[단계 혼재 vs 단계 분리]

❌ 전통적 혼재 방식 (문제: 무엇이 무엇을 cause했는지 불분명)
┌─────────────────────────────────────────────────────────────┐
│  소스 코드 ──┬─── 빌드 ───┼─── 설정 ───┼─── 실행 ───▶ 실행 중인 앱
│             │    │        │    │       │                     │
│             │  코드 수정  │ 설정 수정 │ 런타임 수정          │
│             │  (언제? 누가?)│ (어디에?)  │ (왜?)              │
└─────────────────────────────────────────────────────────────┘
  문제: 각 단계의 변경 이력이 혼잡, 롤백 시 무엇을 롤백해야?

✓ 12팩터 방식 (세 단계 엄격 분리)
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  [Stage 1: BUILD]                                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 소스 코드 (Git Commit a1b2c3d)                       │   │
│  │          │                                            │   │
│  │          ▼                                            │   │
│  │ 실행 가능한 아티팩트 (Docker Image: app:v1.2.3)      │   │
│  └─────────────────────────────────────────────────────┘   │
│                        │                                   │
│                        ▼                                   │
│  [Stage 2: RELEASE]                                         │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 아티팩트 (app:v1.2.3) + 설정 (production config)    │   │
│  │          │                                            │   │
│  │          ▼                                            │   │
│  │ 배포 가능한 패키지 (Release v1.2.3-prod-20240405)   │   │
│  └─────────────────────────────────────────────────────┘   │
│                        │                                   │
│                        ▼                                   │
│  [Stage 3: RUN]                                            │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 런타임에서 실행 (컨테이너/프로세스)                          │   │
│  │ - 특정 버전의 앱이 특정 설정으로 동작                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  장점: 각 단계가 독립적으로 추적/관리 가능                    │
└─────────────────────────────────────────────────────────────┘

📢 섹션 요약 비유: 빌드/릴리스/실행 분리는"음식의 조리 단계"와 같다. 요리(빌드)는 요리사가 하고, 플레이팅(릴리스)은 웨이터가 하며, 서빙(실행)은 호스트가 한다. 만약 맛(설정)이 잘못되었으면 요리사는 플레이팅 담당자에게 돌아가서 새 음식을 요청할 수 있고(릴리스 재실행), 서빙 단계에서 문제가 있으면 호스트가 새로운 접시를 요청할 수 있다(재실행).


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

세 단계가 어떻게 구현되고, CI/CD 파이프라인에서 어떻게 활용되는지 상세히 분석한다.

단계입력출력담당핵심 특성
빌드 (Build)소스코드 (Git Commit)실행 가능한 아티팩트 (바이너리/이미지)CI 파이프라인불변성 (같은 입력 = 같은 출력)
릴리스 (Release)아티팩트 + 환경 설정배포 가능한 패키지CD 파이프라인추적 가능성 (버전 + 설정 조합)
실행 (Run)배포 패키지런타임 프로세스컨테이너 오케스트레이터멱등성 (재실행해도 동일 결과)

아래는 CI/CD 파이프라인에서의 빌드/릴리스/실행 단계를 보여주는 ASCII 다이어그램이다.

[CI/CD 파이프라인에서의 빌드/릴리스/실행]

┌─────────────────────────────────────────────────────────────────────┐
│                        CI/CD 파이프라인                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  1. BUILD 단계                                                       │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  Git Repository                    CI Pipeline                │  │
│  │  ┌──────────────┐                  ┌──────────────────────┐   │  │
│  │  │ Commit       │ ──WebHook 트리거─▶ │ 빌드 (Build)         │   │  │
│  │  │ a1b2c3d      │                  │ - 의존성 설치         │   │  │
│  │  │ (소스 코드)   │                  │ - 컴파일/번들링       │   │  │
│  │  └──────────────┘                  │ - 테스트 실행         │   │  │
│  │                                      │ = Docker Image       │   │  │
│  │                                      │   app:a1b2c3d        │   │  │
│  │                                      └──────────┬───────────┘  │  │
│  └─────────────────────────────────────────────────┼──────────────┘  │
│                                                      │                 │
│                                                      ▼                 │
│  2. RELEASE 단계                                                      │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                           CD Pipeline                          │  │
│  │  ┌──────────────────────┐    ┌──────────────────────────┐   │  │
│  │  │ 아티팩트 (Build)      │    │ 릴리스 (Release)          │   │  │
│  │  │ app:a1b2c3d          │ +  │ - 환경 설정 injection   │   │  │
│  │  └──────────────────────┘    │ - 버전 태그 생성          │   │  │
│  │                               │ = Release a1b2c3d-prod   │   │  │
│  │                               └──────────┬───────────┘   │  │
│  └──────────────────────────────────────────────┼──────────────┘  │
│                                                     │                 │
│                                                     ▼                 │
│  3. RUN 단계                                                           │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                        Kubernetes / Container Runtime          │  │
│  │  ┌──────────────────────────────────────────────────────┐   │  │
│  │  │  실행 (Run)                                           │   │  │
│  │  │  - Release a1b2c3d-prod 이미지 가져옴                  │   │  │
│  │  │  - 환경 변수/시크릿 주입                              │   │  │
│  │  │  - 컨테이너 시작                                       │   │  │
│  │  │  = 실행 중인 앱 (a1b2c3d, production 환경)             │   │  │
│  │  └──────────────────────────────────────────────────────┘   │  │
│  └───────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

📢 섹션 요약 비유: 빌드/릴리스/실행은"영화 제작의 단계"와 같다. 빌드는 촬영(소스 → 영상물)으로, 릴리스는 편집과 배급용 Master 생성(영상물 + 자막/설정), 실행은 영화관 상영(Master → 스크린投影)과 같다. 만약 자막에 문제가 있으면(설정 문제) 편집 단계만 다시 하고, 영화관 장비 문제면(실행 문제) 장비만 다시 조정하면 된다.


Ⅲ. 융합 비교 및 다각도 분석 (Comparison & Synergy)

빌드/릴리스/실행 원칙은 GitOps, IaC, 컨테이너 기술과 결합하여 현대적 DevOps의 핵심 토대가 된다.

관련 개념빌드/릴리스/실행 원칙과의 결합시너지 효과
GitOps빌드 → Git Commit, 릴리스 → Git Tag, 실행 → ArgoCD Sync변경 이력 완벽 추적
IaC빌드 = 코드 컴파일, 릴리스 = 인프라 프로비저닝, 실행 = 인프라 가동인프라도 동일한 원칙 적용
Docker빌드 = Dockerfile 빌드, 릴리스 = 이미지 + 설정, 실행 = docker run컨테이너의 불변성 보장
CI/CD각 단계가 파이프라인의 Stage로 구현자동화된 빌드/릴리스/실행
롤링 배포새 버전 빌드 → 새 릴리스 생성 → 점진적 실행 전환무중단 업데이트

특히 GitOps와의 결합은 빌드/릴리스/실행 원칙의 추적 가능성을 완벽하게 한다. Git Repo의 커밋 히스토리가 빌드 이력이 되고, 릴리스 태그가 실행 환경을 결정하며, ArgoCD나 FluxCD가 실행 단계를 자동화한다.

[GitOps + 빌드/릴리스/실행의 결합]

Git Repository
┌─────────────────────────────────────────────────────────────┐
│  Commit a1b2c3d: "버그 픽스 - 결제 API 오류 수정"              │
│       │                                                      │
│       ├──▶ CI Pipeline: Build (Docker Image: app:a1b2c3d)   │
│       │                                                      │
│       └──▶ Git Tag: v1.2.3-prod                                │
│                   │                                           │
│                   ▼                                           │
│  ArgoCD / FluxCD (GitOps 에이전트)                              │
│       │                                                       │
│       ├── "v1.2.3-prod" 태그 감시                             │
│       │                                                       │
│       └──▶ Kubernetes: Run (app:a1b2c3d with prod 설정)       │
│                                                             │
│  모니터링/알람 ──▶ 문제 발견 ──▶ "v1.2.3-prod" 롤백 요청       │
│       │                                                       │
│       └──▶ Git Tag: v1.2.2-prod (이전 버전)로 변경            │
│                   │                                           │
│                   ▼                                           │
│           ArgoCD가 이전 버전으로 Sync 실행                       │

📢 섹션 요약 비유: 빌드/릴리스/실행과 GitOps의 결합은"음악 녹음과 음원 배포"에 비유할 수 있다. 녹음실(빌드)에서 음원을 녹음하고, 녹음 파일에 자막/음향 설정(릴리스)을 추가하여 음원 파일을 완성하고, 음원 파일을 음악 스트리밍 플랫폼(실행)에 올려 청중이 들을 수 있게 한다. 만약 음원 자체에 문제가 있으면(빌드) 녹음실로 돌아가서 다시 녹음하고, 음원 파일 설정 문제면(릴리스) 편집실에서 수정하면 된다.


Ⅳ. 실무 적용 및 기술사적 판단 (Strategy & Decision)

실무에서 빌드/릴리스/실행 원칙을 적용할 때 흔히 발생하는 문제와 해결 방안을 분석한다.

1. 실무 의사결정 시나리오

  • 시나리오 A: 빌드 단계에서 설정이 포함되어 환경 이미지를 공통 无法한 상황

    • 상황: Dockerfile 내에서 DATABASE_URL을 하드코딩하여, 개발/프로덕션에 다른 이미지를 사용해야 함.
    • 판단: 이것은 빌드/릴리스/실행 원칙 위반이다. 설정은 빌드가 아닌 릴리스 단계에서 주입되어야 한다. Dockerfile을 수정하여 모든 설정을 제거하고, 런타임에 환경 변수나 명령행 인자로 설정할 수 있게 해야 한다.
  • 시나리오 B: 프로덕션 배포 후 문제 발생 시 빠른 롤백이 필요할 때

    • 상황: 새 버전 배포 직후 예상치 못한 에러가 발생하여 이전 버전으로 빠른 롤백이 필요함.
    • 판단: 빌드/릴리스/실행 원칙이 제대로 적용되어 있으면, 롤백은 단순히 이전 릴리스(버전 태그)로 실행 환경만 동기화하면 된다. GitOps를 사용하면 이전 태그로 되돌리고 ArgoCD가 자동으로 그것을検出して 실행을 시작한다.
[빌드/릴리스/실행 원칙 적용 체크리스트]

□ 빌드 단계
  □ 소스 코드가 동일하면 항상 같은 아티팩트 생성 (불변성)
  □ 설정값이 아티팩트에 하드코딩되지 않음
  □ 빌드가 독립적으로 실행됨 (네트워크 상태 등에 영향 없음)

□ 릴리스 단계
  □ 환경별 설정이 명시적으로 관리됨
  □ 각 릴리스가 고유한 버전으로 식별됨
  □ 이전 릴리스를 추적/취소할 수 있음

□ 실행 단계
  □ 동일한 릴리스의 재실행이 동일한 결과를 보장 (멱등성)
  □ 실행 환경이ephemeral (일회용 컨테이너)
  □ graceful shutdown 지원

📢 섹션 요약 비유: 빌드/릴리스/실행 원칙의 부재는"그릇에 음식을 담아 서빙하는 과정에서 요리 단계까지 하는" 것에 비유할 수 있다. 요리(빌드), 플레이팅(릴리스), 서빙(실행)을 한 그릇에서 모두 하면出了问题时 요리가 맛이 없는지, 그릇 선택이 문제인지, 서빙 방법이 문제인지 알 수 없다.


Ⅴ. 기대효과 및 결론 (Future & Standard)

빌드/릴리스/실행 원칙의 올바른 적용은 배포의 신뢰성, 추적 가능성, 그리고 운영 효율성을 크게 향상시킨다.

관점단계 혼재 (AS-IS)단계 분리 (TO-BE)핵심 성과 지표
추적 가능성어떤 버전+설정이 배포되었는지 불분명모든 배포가"버전+설정" 조합으로 추적 가능배포 이력 100% 투명
롤백 속도빌드부터 다시 시작하므로 수십 분이전 릴리스로 즉시 전환 (수초~수분)MTTR 70% 단축
빌드 재현성환경에 따라 빌드 결과 다름동일한 입력 = 동일한 출력빌드 신뢰도 100%
배포 신뢰성설정이 빌드에 포함되어 오류 발생 가능설정은 런타임에 주입배포 실패율 감소

미래 전망 및 결론: 빌드/릴리스/실행 원칙은 Docker, Kubernetes 기술과 결합하여 현대 소프트웨어 배포의 표준이 되었다. 특히 불변 인프라 개념과 결합하면, 한번 빌드된 이미지는 결코 변경되지 않고, 설정만 달리하여 여러 환경에 배포되는"설정 as 코드"패턴으로 발전했다.

결론적으로, 빌드/릴리스/실행 원칙은 12팩터 앱의 제5원칙으로, 소프트웨어 배포의 신뢰성과 효율성을 보장하는 기본적인 방법론이다. 이 원칙을 엄격히 준수하면 문제 발생 시 빠른 근본 원인 분석과 빠른 롤백이 가능해지며, 궁극적으로 더 안정적인 서비스 제공과 더 빠른 기능 업데이트가 가능해진다.

📢 섹션 요약 비유: 빌드/릴리스/실행 원칙은"자동차 제조의 생산라인"과 같다. 공장에서 자동차 본체(빌드)를 만들고, 색상과 옵션을 선택(릴리스)하여 완성된 자동차로 만들고, 고객에게 인도하여 운행(실행)한다. 만약 색상(설정)에 문제가 있으면 페인트 工程(릴리스)만 다시 하면 되고, 엔진 문제면(빌드) 제조 공정을 다시 해야 한다.