The Twelve-Factor App

2. 의존성(Dependencies)

명시적인 의존성 선언과 분리

대부분의 프로그래밍 언어들은 Perl의 CPAN이나 루비의 RubyGem 같은 의존 라이브러리 관리를 위한 패키지 관리 시스템을 제공한다. 패키지 관리 시스템을 통한 라이브러리 설치는 “site packages”라고 불리는 시스템 전체에 적용되는 설치와 “vendoring”이나 “bundling”라고 불리는 어플리케이션이 포함된 디렉토리에만 적용되는 설치, 두 가지로 나뉜다.

Twelve-Factor App은 결코 시스템 전체에 적용되는 패키지가 설치되어있다고 암묵적으로 전제하지 않는다. 모든 의존 관계는 의존성 선언(dependency declaration)을 통해서 완전하고 정확하게 선언되어야한다. 나아가 어플리케이션 실행 중에는 의존성 분리(dependency isolation) 도구를 사용해 어플리케이션에서만 사용되는 의존 라이브러리가 암묵적으로 외부에 공개되지 않도록 해야한다. 의존성 선언은 명시적이어야하며 모든 의존 라이브러리를 포함해야한다. 이러한 의존성 선언은 개발 환경과 프로덕션 환경 모두에 적용된다.

예를 들어 루비에서 사용되는 Gem BundlerGemfile 형식을 의존성 정의에 사용하며 bundle exec를 통해서 의존성을 분리한다. 파이썬에서는 이러한 작업이 두 단계에 걸쳐서 이루어진다. Pip는 의존성 선언에 사용되며, Virtualenv는 의존성 분리에 사용된다. 심지어 C에서도 Autoconf를 통해 의존성 선언을 할 수 있으며, 정적 링크를 이용해 의존성 분리를 실현할 수 있다. 어떤 도구를 사용하건 간에 의존관계 선언과 분리는 항상 함께 사용되어야 한다. 어느 한 쪽만을 사용하는 것은 Twelve Factor를 만족하지 않는다.

의존성을 명시적으로 선언함으로써 얻는 다른 효과는 새로운 프로그래머가 어플리케이션 개발에 참여할 때 개발 환경을 쉽게 구성할 수 있다는 점이다. 새로운 프로그래머가 어플리케이션의 코드베이스를 개발 머신에 가져오는 데 필요한 것은 개발에 사용되는 프로그래밍 언어 런타임과 의존성 관리 도구뿐이다. 여기에 빌드 명령어 하나면 어플리케이션 개발에 필요한 모든 설정을 할 수 있다. 예를 들어 루비 번들러에서는 bundle install을 실행하면 되고, 클로저(Clojure) Leiningen에서는 lein deps 명령어를 실행하면 된다.

또한 Twelve-Factor App은 시스템 전체에 적용되는 특정한 프로그램이 설치되어있다고 전제하지 않는다. 어플리케이션에서는 이미지 편집을 위해 ImageMagick을 사용하거나 웹 페이지 접근을 위해 curl을 사용하기도 한다. 이러한 프로그램들은 대개 시스템 기반으로 설치되는데, 미래에 이 어플리케이션이 실행될 모든 시스템에 이 프로그램이 설치되어있다고 단언할 수 없으며, 설사 설치되어있다고 해도 어플리케이션과 호환되는 버전이라는 보장은 어디에도 없다. 어플리케이션에서 외부 프로그램을 사용하는 경우엔 그 프로그램을 어플리케이션에 포함해야한다.