Twelve Factor APPについてのまとめ(前半)


はじめに

https://12factor.net/ja/ に書いてある内容を自分なりに噛み砕いてまとめました。

Twelve Factor APPとは

現代では、ソフトウェアはWEBアプリケーションや、Software as a Serviceという形で提供されています。Twelve Factor APPは、そのようなソフトウェアを次のようなものにするための方法論です。

  • わずかな時間とコストでプロジェクトに新しい開発者が参加できる
  • 実行環境間での移植性が高い
  • クラウドプラットフォームを利用することでサーバー管理やシステム管理が不要
  • 継続的デプロイが可能
  • 低コストでスケールアップが可能

Twelve-Factorの方法論は、プログラミング言語やバックエンドサービス(データベース、メッセージキュー、メモリキャッシュなど)に依存しておらずどのようなものにでも適用可能です。

Twelve Factor APPはその名の通り12のファクター(要因)があります。

Ⅰ. コードベース

  • Twelve-Factor Appはバージョン管理システムで管理される
  • コードベースとアプリケーションは 1:1の関係である

ここで、コードベースとはアプリケーションを構成するソースコードの集合のことです。プロジェクトやリポジトリと言った方がしっくりくるかもしれません。重要なのは、1つのアプリケーションに対して2つ以上のコードベースがあってはならないということです(コードベースがライブラリなどの外部のコードを利用するのはOK)。
また、実際に動作しているアプリケーションのことをアプリケーションのデプロイと呼びます。アプリケーション:コードベース = 1:1ですが、アプリケーション:デプロイ = 1:n でもOKです。例えば、一つのアプリケーションでも、本番で動いているアプリケーション/ステージング環境で動いているアプリケーション/ローカルで動いているアプリケーションなどの複数のデプロイがあります。しかしこれらは(バージョンの違いを除けば)一つのコードベースを参照していると言えます。

II. 依存関係

  • 依存関係の定義にはパッケージ管理システムを用いる
  • アプリケーションが依存する物は全て依存関係宣言マニフェストで宣言する。
  • 依存関係宣言マニフェストで宣言された物は依存関係分離ツールを用いてインストールする

抽象的な表現が多かったので、言語ごとに例をあげると次のような物になると思います。要はシステムにグローバルにインストールしたパッケージではなく、プロジェクト用にインストールされたパッケージを使用せよということだと理解すれば良いかと思います。
また、アプリケーションがImageMagickやcurlなどのどこにでもありそうなシステムツールに依存する場合でも、それらをアプリケーションの依存として定義する、またはアプリケーション自体に組み込む必要があります。

言語 パッケージ管理ツール 依存関係マニフェスト 依存関係分離ツール
Ruby Bundler Gemfile bundle exec
Python Pip Pipfile Virtualenv
PHP Composer composer.json composer install & autoload.phpの読み込み

このようにしておくことで、後から参加した開発者も環境構築が容易になり、デプロイ先の環境が変わってもシステムツールの有無に振り回されることがなくなります。

Ⅲ. 設定

  • デプロイごとに異なる設定項目は環境変数へ格納する

当たり前のことですが、デプロイ環境ごとに異なるアプリケーションの設定項目をソースコードにハードコーディングしてはいけません。Railsではバージョン管理システムの配下におかない、config/database.ymlなどに設定を記述したりしますが、Twelve-Factor Appはこれすらも推奨していません。何故なら、誤ってgitの管理下においてしまうこともあり、設定をtest, prodなど環境ごとにグルーピングする際、デプロイ先が増えるごとに新たな環境(develop, staging, my-stagingなど)が必要となるため管理が大変になり、スケールアップが難しいためです。
代わりに、環境変数をデプロイごとに独立して管理することでスムーズにスケールアップさせることができるようになります。

Ⅳ. バックエンドサービス

  • バックエンドサービスをアタッチされたリソースとして扱う

バックエンドサービスの例としてはmysqlなどのDBやPostfixなどのSMTPサービス、Memcachedなどのキャッシュシステムなどがあります。これらサービスはローカルで動いている可能性もあれば、サードパーティによって提供されていることもあります。Twelve-Factor Appは、これらがどこでどのように動いているかには関心は持たず、先に述べた設定項目を変えるだけで、一切コードに手を加えることなくバックエンドサービスを自由にアタッチしたりデタッチすることができる必要があります。

Ⅴ. ビルド、リリース、実行

  • アプリケーションのデプロイへの変換をビルド、リリース、実行の3つのステップへ分ける
  • 全てのリリースは全て一意の識別子を持つ
  • 作成されたリリースは変更しない。更新する場合は新しいリリースを作成する

実行に動作しているアプリケーションをデプロイと呼ぶことは先に説明しましたが、このデプロイの状態へアプリケーションを変換するまでに3つのステップを経ます。ソースコードをコンパイルしたものをビルド、ビルドに対して各種設定を適用した物をリリースと呼びます。デプロイツールは通常、リリースをロールバックさせたり等のリリース管理の仕組みを持っています。このため、各リリースには一意の識別子が必要です。
また、実行ステップにあるソースコードを変更しても、それはそのデプロイにしか適用されずビルド、強いてはコードベースへは適用されないのでやってはいけません。

Ⅵ. プロセス

  • Twelve-Factor App はステートレスかつ、シェアードナッシングである

アプリケーションが状態を持つ必要がある時は、データベースなどの永続化可能なバックエンドサービスを使用する必要があります。メモリやディスクにキャッシュされた物は、プロセスが再起動やデプロイなどによって意図せず消えてしまうことがあるので、これらは短いトランザクション以外では使用してはいけません。

続き

後半へ続く