GitLab CI/CDでHerokuアプリをステージングおよび本番環境にデプロイする

前回の記事では、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に同じアプリをデプロイしますが、今回はステージング環境として使用します。これで、あなたの環境が両方設定されました!

プロダクションアプリとステージングアプリのコマンドの違いと共通点に注意してください:

  1. プロダクションアプリはmainブランチを使用し、ステージングアプリはdevブランチを使用します。
  2. プロダクションアプリはheroku-gitlab-ci-cd-productionと呼ばれ、ステージングアプリはheroku-gitlab-ci-cd-stagingと呼ばれます。
  3. プロダクションアプリのgitリモートはheroku-productionと呼ばれ、ステージングアプリのgitリモートはheroku-stagingと呼ばれます。
  4. プロダクションアプリとステージングアプリのgitリモートはどちらもmainブランチを使用しています。なぜなら、Herokuはメインブランチにコードがプッシュされたときにのみアプリをデプロイするからです。

次の点に注意してください:このmainブランチは、あなたのセットのmaindevブランチとは異なります。ここでプッシュしているmainブランチは、gitリモート上のmainブランチであり、この場合ではHerokuです。

あなたがローカルのmainブランチにいるときにgit push heroku-production mainを実行すると、あなたのmainブランチをHerokuプロダクションアプリのmainブランチにプッシュしています。そして、あなたがローカルのdevブランチにいるときにgit push heroku-staging mainを実行すると、あなたのdevブランチをHerokuステージングアプリのmainブランチにプッシュしています。

アプリに変更を加える

Herokuアプリが動いていますが、変更を加えたい場合どうしますか?Gitflowブランチ戦略の大まかな近似に従って、以下のようにすることができます:

  1. devブランチをチェックアウトする
  2. コードに変更を加える
  3. 変更を追加、コミットし、devブランチにプッシュする
  4. ステージングHerokuアプリに変更をデプロイするためにgit push heroku-staging mainを実行する
  5. mainブランチをチェックアウトする
  6. devブランチをmainブランチにマージする
  7. プロダクション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ファイルを使用します。私たちのファイルは以下のようになります:

YAML

 

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つのステージがあります:testdeploytestステージでは、unit-test-jobでユニットテストを実行します。deployステージでは、deploy-jobでアプリをHerokuにデプロイします。

前のステージのすべてのジョブがパスした場合にのみ、次のステージに進むことができます。つまり、ユニットテストが失敗した場合、アプリはデプロイされません。これは良いことです!アプリが不良状態でデプロイされることは望みません。

デプロイステージには、コードのdeployrulesセクションがあり、ここには条件付きロジックが含まれています。ここで、私たちのアプリがどの環境にデプロイされるべきかを指定します。メインブランチにいる場合、私たちのプロダクションアプリをデプロイします。デバッグブランチにいる場合、私たちのステージングアプリをデプロイします。

また、デプロイステージは、$HEROKU_APP_NAME_PRODUCTION$HEROKU_APP_NAME_STAGING$HEROKU_API_KEYといういくつかの変数を参照していることも気づくでしょう。これらはGitLabのCI/CD変数として保存されています

自分のGitLabアカウントで設定する場合、まずHerokuアカウントでAPIキーを見つける必要があります。Herokuアカウントの設定内には、APIキーのセクションがあります。まだAPIキーを生成していない場合は、今生成してください。

Heroku API key

次に、GitLabプロジェクトで設定 > CI/CD > 変数をクリックします。そのセクションを展開し、3つの新しい変数を追加します:

  1. $HEROKU_API_KEYの値は、HerokuアカウントからのAPIキーです。
  2. $HEROKU_APP_NAME_PRODUCTIONの値は、プロダクションHerokuアプリの名前です。私のプロダクションアプリの名前はheroku-gitlab-ci-cd-productionですが、Herokuアプリ名は世界で唯一ですので、 yoursは異なる名前になります。
  3. HEROKU_APP_NAME_STAGINGの値は、ステージング環境のHerokuアプリの名前です。私のステージングアプリの名前はheroku-gitlab-ci-cd-stagingです。そして再び、Herokuアプリの名前は世界で唯一であるため、あなたのものは異なるものになるでしょう。
GitLab CI/CD variables

それで、GitLab CIパイプラインは準備ができました!テストしてみましょう。

Herokuアプリをステージング環境にデプロイする

まずdevブランチをチェックアウトし、アプリのコードに変更を加えましょう。私はヘッダーテキストを簡単に変更し、UIのテキストに複数の新しい行を追加しました。あなたも同じような変更をコードに加えることができます。

その変更を追加し、コミットし、devブランチにプッシュします。これによりGitLab CIパイプラインが開始されます。GitLab内でパイプラインを表示し、リアルタイムで進捗を確認できます。

GitLab CI pipeline build for the dev branch

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

Demo Heroku app with updated copy

ステージング環境を設定することで、ホスティング環境でコードを手動でテストするのに最適な場所が得られます。また、QAテスターまたはプロダクトマネージャーが本番環境に移行する前に変更を確認するのに完璧な場所でもあります。

今、本番アプリのURLをチェックアウトしてください。まだ最新の変更が反映されていない古いUIが表示されていることに気づくでしょう。これは、GitLab CIパイプラインが変更をステージング環境にのみデプロイしたためで、本番環境にはデプロイされていないからです。

コードがステージング環境で問題ないことを確認したので、プロダクション環境に移行しましょう。

プロダクション環境へのHerokuアプリのデプロイ

まずmainブランチをチェックアウトし、その後devブランチをあなたのmainブランチにマージします。プルリクエストを通じて、またはgit merge devを実行してからgit pushを実行してこれを行うことができます。

これにより、GitLab CIパイプラインが再び開始され、今回はあなたのプロダクションアプリのデプロイ準備が行われます。

GitLab CI pipeline build for the main branch

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

All GitLab CI pipeline builds

パイプラインが完了したら、プロダクションの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