開発と設定の原則
最終更新日 2024年05月07日(火)
Table of Contents
Heroku をデプロイ環境として使用すると、アプリケーションのランタイム部分に影響を与えるだけでなく、その開発プロセスにも影響を与えます。ここで説明するのは、Heroku での開発体験を中心にしたアプリケーション開発および設定のいくつかの原則です。
これらの開発および設定原則は、Heroku で開発するときのさまざまなカテゴリのベストプラクティスの 1 つです。アプリケーション設計の原則をすべて見直して、Heroku でのアプリの適正な開発について十分に理解しましょう。
アプリケーションとコードベース
アプリを開発するとき、作業のほとんどが行われるアプリケーションのコードベースは、いくつかの形式のバージョン管理システム (VCS) (GitHub (推奨)、GitLab、BitBucket など) で保管されます。VCS は数多くのコードベースのリビジョンの経過を追跡し、あらゆる規模の開発チームの中でソースコードに対する修正を調整します。
Heroku へのデプロイで、アプリは Git VCS を介して送信されます。Git は非常に有能な VCS ですが、必ずしもプライマリ VCS として使用して Heroku にデプロイする必要はありません。開発ワークフローと組織上の制約に合わせて適正なツールを自由に選べます。
アプリケーションを開発するとき、どの時点においても実行されるそのアプリケーションの複数のバージョンが必要になります。開発部門をローカルで運営して、関係者が最新機能を利用できるステージング環境バージョン、エンドユーザーのために承認された、安定したバージョンだけを搭載した本番環境バージョンを運営することを検討しましょう。
Heroku では、複数の開発環境(たとえば、ステージング、QA、本番など) を、各環境用の Heroku アプリを作成することで、維持します。各環境に適切なコードベースリビジョンを、対応する Heroku 上のアプリにデプロイするだけです。
アプリとそのステージの間の関連を明確にするため、各 Heroku アプリを環境 (myapp
、myapp-staging
、myapp-qa
) に従ってネームスペースを指定します。
代わりとして、Heroku パイプラインを検討してください。
複数のコードベースがありこれらが機能システムを形成している場合、各構成要素を独立したアプリとしてデプロイして (各アプリがそれぞれの環境固有デプロイ)、これらが一斉に分散システムを形成するようにします。
高い開発速度を維持したい複雑なシステムはこのパターンに従い、独立しているが協調的なアプリを作成して、これらが協力して必要な機能を発揮するようにする必要があります。エンドユーザーのセグメントに基づいた責任の分離 (たとえば myapp
、myapp-admin
、myapp-api
) が見られることがよくあります。これにより確立される明確に定義された責任の領域とアプリ間の統合ポイントは、大きなモノリシックアプリケーションによく現れる全体的な複雑さを解消します。
大量のコンポーネントや環境を備えたアプリは Terraform や Heroku API のようなツールを使用して、デプロイ間のプロビジョニングや状態を管理できます。
Heroku Git はデプロイのための便宜的なものであり、安定した Git リポジトリのためのものではありません。コードベースを追跡するには、GitHub (推奨)、GitLab、BitBucket などのバージョン管理システムを使用してください。
依存関係
アプリケーションの依存関係 (プラグインや必須のサードパーティライブラリなど) を明確にして隔離するべきです。Heroku ランタイムで既にインストールされたパッケージへの依存はないはずです。依存関係がこの方法で隔離されるとき、新しい環境の例示化は大した問題ではなく、システムから非互換バージョンが漏れることはありません。
すべての近代言語ツールチェーンが、依存関係の公表と隔離をサポートします。Ruby の bundler と bundle exec
、Python の Pip および Virtualenv、Clojure の Leiningen などを考えてみましょう。アプリを Heroku にデプロイするとき、これらの依存関係が取り出されてアプリと並行して保存されることで、分離し、圧縮された実行可能なアプリのバージョン (スラグと呼ばれる) が作成されます。
言語固有でない依存関係 (バイナリ実行ファイルなど) を、アプリケーションコードベースとともにベンダリング、あるいは保管する必要があります。
設定
アプリの設定は、すべて、デプロイ (ステージング環境、本番環境、開発環境など) によって変わる可能性があります。これには、データベースおよび他のバッキングサービスロケーション、サードパーティー認証情報 (AWS や Twitter)、そしてデプロイ毎の設定 (ホスト名や同時レベル) が含まれます。
このような設定はコードベースに保管すべきでありません。これによりバージョン管理システム内のプライベートリソースがむき出しになり、各環境間で不要なコード修正が必要になります。
Heroku では、アプリケーション設定は環境変数で heroku config
を使用して指定します。ローカル開発では同じパターンに従うだけでなく、設定データをローカル環境に保存し、Heroku Local のようなツールを使用して環境管理を支援します。
バッキングサービス
バッキングサービス (アプリがネットワーク上でその通常操作の一部として使用するサービス) は、URL または設定に保管されている他のロケーター/認証情報を介して、アプリに結合しています。たとえば、MongoDB や PostgreSQL、メッセージキュー、メールサービスなどのデータストアがすべてアプリの設定で URL として指定されます。
外部リソースをこのように消費することで、速く簡単にプロバイダーをスワップアウトしたりランタイムサービスを修正できます。コードや、アドオンマーケットプレイスでのプロビジョニング方法の変更は不要です。
開発/本番パリティ
Heroku 上のアプリを連続したデプロイのために設計するには、時間、個人、そしてツールの開発環境と本番環境の間のギャップをできるだけ小さくする必要があります。アプリケーションの開発と本番環境での実行の間に相違があるとわずかな不和合性が生じ、開発環境やステージング環境で機能していたコードが本番環境で失敗する可能性があります。
たとえば、開発環境と本番環境の間で異なるサービスを使用するのは、アダプターがサービスにおける差異を理論的に除去する場合でもやめましょう。SQLite をローカルで使用して PostgreSQL を本番環境で使用したり、キャッシュ用のローカルプロセスメモリを開発環境で使用して Memcached を本番環境で使用すると、最初は無害に見えても、さまざまな本番環境で問題が生じる可能性があります。