前回の記事では、GitLab CI/CDを使用してHerokuにデプロイを自動化する方法を探求しました。その設定では、コードをmain
ブランチにプッシュするたびにアプリを本番環境にデプロイしていました。
この記事では、少し bardziej 詳細なアプローチを考えます:複数の環境がある場合どうでしょうか?多くのエンジニアリング組織は少なくとも3つの環境を使用しています:ローカル開発環境、ステージング環境、そして本番環境。
また、一部のエンジニアリングチームはGitflowブランチ戦略を従っており、dev
ブランチとmain
ブランチを持っています。この戦略は現在はトランクベース開発に取って代わられてしまい、人気は衰えていますが、このプラクティスをまだ従っている組織は珍しくありません。
今日は、GitLab CI/CDを設定して、dev
ブランチにプッシュしたときにスタージング環境にアプリをデプロイし、main
ブランチにプッシュしたときにプロダクション環境にアプリをデプロイする方法を見ていきます。
始めに
始める前に、以下の2つのものが必要です:HerokuアカウントとGitLabアカウント。
Herokuはアプリのホスティングとデプロイに最適な場所です。プラットフォーム・アズ・ア・サービス(PaaS)としてのHerokuは、インフラの複雑さを抽象化して、面白いものを構築に集中できるようにしてくれます。ここでHerokuアカウントを作成することができます。
GitLabはコードを保存するのに最適な場所です。ソースコード管理ツールとしてだけでなく、GitLabはネイティブなCI/CD機能も提供しており、別の第三者ツールを使用することなく、パイプラインを設定してコードをテストおよびデプロイすることができます。ここでGitLabアカウントを作成することができます。
この記事で示されるデモアプリはGitLabとHerokuの両方を使用しています。すべてのコードはここでGitLabリポジトリで見つけることができます。
ローカルでアプリを実行する
ローカルでアプリを実行するには、リポジトリをクローンし、依存関係をインストールし、スタートコマンドを実行します。ターミナルで以下を行ってください:
$ git clone https://gitlab.com/tylerhawkins1/heroku-gitflow-staging-production-gitlab-cicd-demo.git $ cd heroku-gitflow-staging-production-gitlab-cicd-demo $ npm install $ npm start
アプリを起動した後、ブラウザでこのローカルホストにアクセスすると、ローカルで動作しているアプリが表示されます:
デモのHerokuアプリ
アプリをHerokuにデプロイ
アプリがローカルで動作しているので、Herokuにデプロイしてどこからでもアクセスできるようにしましょう。
スタージング環境と本番環境の両方にアプリをデプロイするので、同じGitLabリポジトリに基づく二つのHerokuアプリを作成します。
既にHeroku CLIがインストールされていない場合は、進む前にインストールしてください。
Heroku CLIをインストールした後、ターミナルから以下のコマンドを実行して、main
ブランチをチェックアウトし、新しい本番用Herokuアプリを作成し、本番環境にデプロイし、ブラウザで開きます:
$ git checkout main $ heroku create heroku-gitlab-ci-cd-production --remote heroku-production $ git push heroku-production main $ heroku open --remote heroku-production
これで、ローカルホストではなくHeroku URLで動作している同じアプリが表示されるはずです。お疲れ様です — Herokuアプリを本番にデプロイしました!
まだ終わりではありません。スタージングアプリも設定してデプロイする必要があります。そのためには、以下に示される同じようなコマンドを実行してください:
$ git checkout dev $ heroku create heroku-gitlab-ci-cd-staging --remote heroku-staging $ git push heroku-staging main $ heroku open --remote heroku-staging
今度は異なるURLに同じアプリをデプロイしますが、今回はステージング環境として使用します。これで、あなたの環境が両方設定されました!
プロダクションアプリとステージングアプリのコマンドの違いと共通点に注意してください:
- プロダクションアプリは
main
ブランチを使用し、ステージングアプリはdev
ブランチを使用します。 - プロダクションアプリは
heroku-gitlab-ci-cd-production
と呼ばれ、ステージングアプリはheroku-gitlab-ci-cd-staging
と呼ばれます。 - プロダクションアプリのgitリモートは
heroku-production
と呼ばれ、ステージングアプリのgitリモートはheroku-staging
と呼ばれます。 - プロダクションアプリとステージングアプリのgitリモートはどちらも
main
ブランチを使用しています。なぜなら、Herokuはメインブランチにコードがプッシュされたときにのみアプリをデプロイするからです。
次の点に注意してください:このmain
ブランチは、あなたのセットのmain
とdev
ブランチとは異なります。ここでプッシュしているmain
ブランチは、gitリモート上のmain
ブランチであり、この場合ではHerokuです。
あなたがローカルのmain
ブランチにいるときにgit push heroku-production main
を実行すると、あなたのmain
ブランチをHerokuプロダクションアプリのmain
ブランチにプッシュしています。そして、あなたがローカルのdev
ブランチにいるときにgit push heroku-staging main
を実行すると、あなたのdev
ブランチをHerokuステージングアプリのmain
ブランチにプッシュしています。
アプリに変更を加える
Herokuアプリが動いていますが、変更を加えたい場合どうしますか?Gitflowブランチ戦略の大まかな近似に従って、以下のようにすることができます:
dev
ブランチをチェックアウトする- コードに変更を加える
- 変更を追加、コミットし、
dev
ブランチにプッシュする - ステージングHerokuアプリに変更をデプロイするために
git push heroku-staging main
を実行する main
ブランチをチェックアウトするdev
ブランチをmain
ブランチにマージする- プロダクションHerokuアプリに変更をデプロイするために
git push heroku-production main
を実行する
(本当にGitflowに従っている場合、dev
にマージするフィーチャーブランチを作成し、main
にマージするリリースブランチを作成しますが、ここでは手順をシンプルにするために省略しています。)
さて、毎回手動でデプロイする代わりに、どちらの環境にも自動的にデプロイできるようになればいいですね。
ここでGitLab CI/CDが登場します。
継続的インテグレーション/継続的デプロイメント
継続的インテグレーション(CI)とは、頻繁にコミットを行い、ビルドを常に良好な状態に保つことです。通常、ビルドが良好な状態にあることをCIパイプライン内でチェックを実行して確認します。これらのチェックには、リinter、ユニットテスト、および/またはエンドツーエンドテストが含まれる可能性があります。
継続的デプロイメント(CD)とは、頻繁にデプロイすることです。CIパイプライン内のチェックがパスした場合、ビルドがデプロイされます。チェックが失敗した場合、ビルドはデプロイされません。
GitLab CI/CDを使用すると、このようにCIパイプラインを設定して、テストを実行し、すべてのテストがパスした場合にアプリをHerokuにデプロイすることができます。最も重要な設定として、CIパイプライン内でアプリがデプロイされる場所を指定するルールを設定することができます。
GitLab CI/CDの設定
GitLabでCIパイプラインをプログラマティカに作成するために、.gitlab-ci.yml
ファイルを使用します。私たちのファイルは以下のようになります:
image: node:20.10.0
cache:
paths:
- node_modules/
before_script:
- node -v
- npm install
stages:
- test
- deploy
unit-test-job:
stage: test
script:
- npm test
deploy-job:
stage: deploy
variables:
HEROKU_APP_NAME: $HEROKU_APP_NAME_PRODUCTION
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
variables:
HEROKU_APP_NAME: $HEROKU_APP_NAME_PRODUCTION
- if: $CI_COMMIT_REF_NAME =~ /dev/
variables:
HEROKU_APP_NAME: $HEROKU_APP_NAME_STAGING
script:
- apt-get update -yq
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY
GitLab CIパイプラインはステージとジョブで構成されます。各ステージには1つ以上のジョブを含むことができます。私たちのパイプラインには2つのステージがあります:test
とdeploy
。test
ステージでは、unit-test-job
でユニットテストを実行します。deploy
ステージでは、deploy-job
でアプリをHerokuにデプロイします。
前のステージのすべてのジョブがパスした場合にのみ、次のステージに進むことができます。つまり、ユニットテストが失敗した場合、アプリはデプロイされません。これは良いことです!アプリが不良状態でデプロイされることは望みません。
デプロイステージには、コードのdeploy
にrules
セクションがあり、ここには条件付きロジックが含まれています。ここで、私たちのアプリがどの環境にデプロイされるべきかを指定します。メインブランチにいる場合、私たちのプロダクションアプリをデプロイします。デバッグブランチにいる場合、私たちのステージングアプリをデプロイします。
また、デプロイステージは、$HEROKU_APP_NAME_PRODUCTION
、$HEROKU_APP_NAME_STAGING
、$HEROKU_API_KEY
といういくつかの変数を参照していることも気づくでしょう。これらはGitLabのCI/CD変数として保存されています。
自分のGitLabアカウントで設定する場合、まずHerokuアカウントでAPIキーを見つける必要があります。Herokuアカウントの設定内には、APIキーのセクションがあります。まだAPIキーを生成していない場合は、今生成してください。

次に、GitLabプロジェクトで設定 > CI/CD > 変数をクリックします。そのセクションを展開し、3つの新しい変数を追加します:
$HEROKU_API_KEY
の値は、HerokuアカウントからのAPIキーです。$HEROKU_APP_NAME_PRODUCTION
の値は、プロダクションHerokuアプリの名前です。私のプロダクションアプリの名前はheroku-gitlab-ci-cd-production
ですが、Herokuアプリ名は世界で唯一ですので、 yoursは異なる名前になります。HEROKU_APP_NAME_STAGINGの値は、ステージング環境のHerokuアプリの名前です。私のステージングアプリの名前は heroku-gitlab-ci-cd-staging
です。そして再び、Herokuアプリの名前は世界で唯一であるため、あなたのものは異なるものになるでしょう。

それで、GitLab CIパイプラインは準備ができました!テストしてみましょう。
Herokuアプリをステージング環境にデプロイする
まずdev
ブランチをチェックアウトし、アプリのコードに変更を加えましょう。私はヘッダーテキストを簡単に変更し、UIのテキストに複数の新しい行を追加しました。あなたも同じような変更をコードに加えることができます。
その変更を追加し、コミットし、dev
ブランチにプッシュします。これによりGitLab CIパイプラインが開始されます。GitLab内でパイプラインを表示し、リアルタイムで進捗を確認できます。

すべてが問題なく進むと、test
とdeploy
の両ステージがパスしたことが確認できるはずです。さあ、ステージング環境のURLでホスティングされたHerokuアプリをチェックアウトしてください。GitLab CIパイプラインがアプリをデプロイしてくれたため、ステージング環境で変更がライブで表示されるはずです!

ステージング環境を設定することで、ホスティング環境でコードを手動でテストするのに最適な場所が得られます。また、QAテスターまたはプロダクトマネージャーが本番環境に移行する前に変更を確認するのに完璧な場所でもあります。
今、本番アプリのURLをチェックアウトしてください。まだ最新の変更が反映されていない古いUIが表示されていることに気づくでしょう。これは、GitLab CIパイプラインが変更をステージング環境にのみデプロイしたためで、本番環境にはデプロイされていないからです。
コードがステージング環境で問題ないことを確認したので、プロダクション環境に移行しましょう。
プロダクション環境へのHerokuアプリのデプロイ
まずmain
ブランチをチェックアウトし、その後dev
ブランチをあなたのmain
ブランチにマージします。プルリクエストを通じて、またはgit merge dev
を実行してからgit push
を実行してこれを行うことができます。
これにより、GitLab CIパイプラインが再び開始され、今回はあなたのプロダクションアプリのデプロイ準備が行われます。

GitLabのパイプラインページですべてのパイプラインの実行を確認することもできます。これにより、dev
およびmain
ブランチの各ビルドを確認できます:

パイプラインが完了したら、プロダクションのHerokuアプリのURLにアクセスしてください。変更がプロダクションでもデプロイされているはずです。素晴らしい仕事ですね!
結論
A good CI pipeline allows you to ship new features quickly and confidently without manually managing the deployment process. Having multiple environments configured for local development, staging, and production gives you more control over where and when code is released.
HerokuとGitLab CI/CDを使用することで、これらすべてを自動化して、DevOpsプロセスを簡単にすることができます!
Source:
https://dzone.com/articles/deploying-heroku-apps-to-staging-and-production