どこかの記事でTwelve Factor Appを見かけて気になったのでまとめました。
Twelve Factor App
Twelve factor appはつぎのようなSaaSを作り上げるためのHerokuの中の人が提唱した、モダンなWebアプリケーションとしてあるべき姿を12のベストプラクティスにまとめた方法論です。
- セットアップ自動化のために 宣言的な フォーマットを使い、プロジェクトに新しく加わった開発者が要する時間とコストを最小化する。
- 下層のOSへの 依存関係を明確化 し、実行環境間での 移植性を最大化 する。
- モダンな クラウドプラットフォーム 上への デプロイ に適しており、サーバー管理やシステム管理を不要なものにする。
- 開発環境と本番環境の 差異を最小限 にし、アジリティを最大化する 継続的デプロイ を可能にする。
- ツール、アーキテクチャ、開発プラクティスを大幅に変更することなく スケールアップ できる。
コードベース
ソースコードとアプリケーションは常に1対1の関係。もし複数のコードベースがある場合、それは分散システムであり、それぞれのコンポーネントがアプリケーションであり、個別にTwelve Factorに適合することができる。同じコードを共有する複数のアプリケーションはTwelve Factorに違反していて、その場合は共通コードをライブラリに分解し、依存関係監理ツールで組み込む。
デプロイは複数存在し、本番サイトとステージングサイト、さらにすべての開発者はローカル環境で動作するアプリケーションのコピーを持っておりこれらもデプロイとみなせる。
依存関係
暗黙的な依存関係は存在せず、ライブラリやシステムツールなどは明示的にしてアプリケーションだけで完結するようにする。なぜならシステムツール(curlなど)は常にデプロイさせる環境で使用できるとは限らないからである。またアプリケーションで完結できれば新たな開発者のセットアップにかかるコスト削減につながる。
設定
コードや設定ファイルに設定を含めるのではなく環境変数として設定するようにする。環境変数ならコードを変更することなくデプロイごとに簡単に変更でき、設定ファイルとは異なり誤ってリポジトリにチェックインされる可能性は低い。コードに含めた場合は環境ごとにビルドが必要になり、設定ファイルの場合は環境ごとにファイルが必要となりスケールしにくくなるため環境変数を使用する。
バックエンドサービス
DBや外部サービスはアタッチ/デタッチ可能なリソースとして捉えコードを修正しなくても変更できるようにする。コードは、ローカルサービスとサードパーティサービスを区別しない。 アプリケーションにとっては、どちらもアタッチされたリソースであり、設定に格納されたURLやその他のロケーター、認証情報でアクセスする。また仮にDBが落ちた場合環境変数を書き変えるだけで別のDBに接続できる。
ビルド、リリース、実行
ビルド、リリース、実行の3つのステージを厳密に分離する。実行ステージはできるだけ可変部分を持たないようにするべきである。なぜならアプリケーションに問題が起きると開発者が待機していない真夜中などにアプリケーションが壊れる可能性があるためである。テスト済みのコードをビルドし、その結果を各環境にリリースして実行するようにする。
プロセス
プロセスはステートレスかつシェアドーナッシング(システムを構成するコンピュータ間で何も共有しない方式のこと。)で永続化する必要のあるすべてのデータは、ステートフルなバックエンドサービスに格納しなければならない。インスタンスは増減するものであり永続的に存在しないからである。永続的に持ちたいデータはDBなどを利用する。
ポートバインディング
アプリケーション内にサーバを組み込み、サーバ単位ではなくポート単位でサービスを公開できるようにする。これにより自分自身もほかのサービスのバックエンドサービスとして機能を提供することが容易になる。
並行性
スケールアップではなくスケールアウトさせるようにする。スケールアップの場合はマシンの再起動が必要となりダウンタイムが発生するため
廃棄容易性
即座に起動・終了することができる。この性質が素早く柔軟なスケールとコードや設定に対する変更の素早いデプロイを容易にし本番デプロイの堅牢性を高める。
開発/本番一致
各環境のギャップを少なくし、できるだけ一致させた状態を保つ
ログ
標準出力に出力させツールで一か所に集約する。スケールイン時に仮想サーバごと消える可能性があることや環境が異なっても常に行えるのでこのようにする。
管理プロセス
管理プロセスはアプリケーションの初期化処理として実行させるようにする。手動で管理を実行するとオペミスが発生する可能性がある。