Article

12 Factor App: 클라우드 네이티브 애플리케이션 설계 방법론

12 Factor App: 클라우드 시대의 필수 설계 원칙

12 Factor는 마이크로서비스와 클라우드 네이티브 애플리케이션이 필수적인 현재, 모든 백엔드 개발자가 알아야 할 최고 수준의 설계 가이드라인입니다. 단순한 선택이 아니라 필수 요구사항입니다.

12 Factor를 따르는 이점

항목효과
배포 자동화개발/테스트/프로덕션 모두 동일한 코드와 설정 사용
수평 확장새로운 서버 추가 시 별도 설정 불필요
무중단 배포Graceful shutdown으로 데이터 손실 방지
환경 독립성로컬에서 개발하면 프로덕션에서도 동일하게 동작
CI/CD 파이프라인자동화된 배포로 배포 속도 극대화

12 Factor의 세부 항목

1. 코드베이스 (Codebase)

원칙: 앱은 한 개의 코드베이스로 관리되며, 동일한 코드로 모든 환경에 배포된다.

  • 앱과 코드베이스는 1:1 관계
  • 개발/스테이징/프로덕션 모두 같은 코드 기반
  • 이는 다른 11가지 전략의 기본 토대

중요도: Required

2. 종속성 (Dependencies)

원칙: 모든 종속성을 명시적으로 선언하여 사용해야 한다.

// package.json, pom.xml 등에 버전 명시
{
  "dependencies": {
    "express": "^4.17.1",
    "mongoose": "^5.12.0"
  }
}
  • dependency manifest 파일에 정확한 버전 명시
  • 빌드 시 자동으로 필요 라이브러리 설치

중요도: High

3. 설정 (Config)

원칙: 환경별로 달라지는 모든 설정은 외부로 분리하여 런타임에 읽어야 한다.

분리해야 할 항목:

  • 데이터베이스 연결 정보
  • 외부 리소스 인증 정보 (S3, Redis 등)
  • 배포 환경별 서로 다른 값 (hostname, port 등)
  • 개발/테스트/스테이징/프로덕션별 설정

절대 금지:

  • 코드에 하드코딩
  • properties 파일에 포함
  • build 파일에 작성
  • 앱 서버 설정에 포함

권장 방식:

  • dotenv 라이브러리 (로컬 환경)
  • Docker 환경 변수
  • Spring Cloud Config (분산 설정)

중요도: Medium

4. 백엔드 서비스 (Backing Services)

원칙: 백엔드 서비스를 연결된 리소스로 취급하여 자유롭게 교체 가능해야 한다.

백엔드 서비스:

  • 데이터베이스
  • 캐시 (Redis, Memcached)
  • 메시지 큐 (RabbitMQ, Kafka)
  • SMTP 서비스
  • 파일 저장소 (S3)

수정 없이 다른 서비스로 전환 가능한 설계가 필수다.

중요도: High

5. 빌드, 릴리즈, 실행 (Build, Release, Run)

원칙: 빌드 > 릴리즈 > 실행 단계를 엄격히 구분해야 한다.

각 단계의 역할:

  • 빌드: 개발자가 실행 (코드 → 실행 가능한 번들)
  • 릴리즈: 빌드 + 설정 조합
  • 실행: 릴리즈를 메모리에 로드하여 실행 (Unique ID 필수)

실행은 복잡하지 않도록 하여 빠르게 시작/종료될 수 있어야 한다.

중요도: Conceptual

6. 프로세스 (Process)

원칙: 앱은 stateless 프로세스로 실행되어야 한다.

  • 여러 인스턴스로 배포되므로 메모리/파일 공유 불가
  • 세션, 파일 등은 모두 외부 리소스 사용 (Redis, S3)
  • 인스턴스 재기동 시 local state 모두 초기화됨

중요도: High

7. 포트 바인딩 (Port Binding)

원칙: 앱은 포트 바인딩을 통해 독립적인 서비스로 동작해야 한다.

  • 모든 요청이 포트로 공개된 서비스에 전달
  • 웹 서버 따로, 앱 따로 필요 없음

중요도: Medium

8. 동시성 (Concurrency)

원칙: 앱은 수평적으로 확장 가능하도록 설계해야 한다.

  • 프로세스별로 역할 분리 (웹, 워커, 어드민 등)
  • 마이크로서비스 패턴 적용 권장
  • 프로세스는 데몬이 아니어야 함

중요도: Low

9. 폐기 가능 (Disposability)

원칙: Shutdown 신호를 받으면 Graceful shutdown을 수행해야 한다.

  • SaaS는 수시로 scale up/down 발생
  • 진행 중인 작업을 완료하고 종료
  • 강제 종료로 인한 데이터 손실 방지

중요도: Medium

10. 개발/프로덕션 일치 (Dev/Prod Parity)

원칙: 개발, 스테이징, 프로덕션 환경을 최대한 동일하게 유지해야 한다.

  • 환경 차이를 최소화하면 예상치 못한 버그 감소
  • 배포 후 문제 발생 시 빠른 대응 가능

중요도: Medium

11. 로그 (Logs)

원칙: 로그를 Event Stream으로 취급하여 로컬에 저장하지 않는다.

  • SaaS는 언제든 생성/삭제 가능한 임시 인스턴스
  • 로컬 저장 시 권한/공간 문제 발생 가능
  • 로그 수집 서비스 (Splunk, ELK)로 중앙화

중요도: Low

12. 어드민 프로세스 (Admin Process)

원칙: 관리 작업을 일회성 프로세스로 실행해야 한다.

일회성 프로세스 예시:

  • 데이터베이스 마이그레이션
  • 데이터 정제 스크립트
  • 수동 성능 분석

메인 앱과 동일한 코드베이스/환경에서 실행되어야 한다.

중요도: High

12 Factor 적용의 실제 효과

배포 자동화

# 같은 코드로 모든 환경에 배포 가능
docker build -t myapp:1.0 .
docker run -e ENV=production myapp:1.0

수평 확장

# 앱 서버 추가 시 다른 설정 불필요
docker run -e ENV=production myapp:1.0
docker run -e ENV=production myapp:1.0
docker run -e ENV=production myapp:1.0

빠른 배포

  • Stateless 설계로 인한 간단한 배포
  • 무중단 배포 가능
  • 롤백도 간단

12 Factor 도입의 실제 효과

배포 과정의 간소화

# 환경별 설정만 다르고 배포 스크립트는 동일
version: '3'
services:
  app:
    image: myapp:1.0
    environment:
      - DATABASE_URL=postgres://...
      - LOG_LEVEL=production

마이크로서비스 아키텍처 구현

각 서비스를 독립적으로 배포하고 확장할 수 있습니다.

# 특정 서비스만 스케일 아웃
docker run -e ENV=production myapp:1.0  # 인스턴스 1
docker run -e ENV=production myapp:1.0  # 인스턴스 2
docker run -e ENV=production myapp:1.0  # 인스턴스 3

팀의 생산성 향상

  • 개발자: 로컬 환경에서 프로덕션과 동일한 환경 구성
  • 운영팀: 예측 가능한 배포 프로세스로 장애 최소화
  • DevOps: 자동화 도구 작성이 간단해짐

마치며

12 Factor는 현대적인 애플리케이션 개발의 기본입니다. 마이크로서비스, 쿠버네티스, 클라우드 인프라 시대에 12 Factor를 무시하면:

  • ❌ 배포 자동화 불가
  • ❌ 수평 확장 곤란
  • ❌ 개발/운영 간 마찰 증가
  • ❌ 버그와 장애 증가

새로운 프로젝트를 시작할 때는 처음부터 12 Factor를 기반으로 설계하는 것이 장기적으로 가장 효율적입니다.

댓글