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를 기반으로 설계하는 것이 장기적으로 가장 효율적입니다.
댓글