python / Django
作成日:2020/3/13 更新日:2020/3/23

DjangoでGCPを活用した実践的な開発 Part5 [ 3.x対応 ]

GCPのCloudBuildでCI/CDを実現する方法について解説しています。CloudBuildで実行する場合、ビルドを実行する環境にプロダクションと同じミドルウェアの依存関係を再現することで、プログラムのミスではなく、ミドルウェアの相性、潜在的な互換性のバグを見つけることが可能になります。

GCPのCloudBuildを使ったCI/CD

CloudBuildは柔軟なコンテナベースの実行環境作成がコンテナイメージを基に行えるので、アプリケーションが依存しているインフラ環境の作成、テスト、静的ファイルの最適化、デプロイ、通知などを容易に実装できます。
※このハンズオンを行うには支払情報を設定したGCPプロジェクトが必要です。

ビルド用の新しいブランチを作成したので、feature/cloudbuildに変更して進めてください。

ksh3/django-startproject
Contribute to ksh3/django-startproject development by creating an account on GitHub.

次にgcloud CLIが無い方はインストールしてパスを通してください。

クイックスタート  |  Cloud SDK のドキュメント  |  Google Cloud

ビルドステップを読み解く

要約して説明すると、依存の注入、テスト、CloudRunへのデプロイといったステップになっています。

steps:
  # アプリが依存しているサービス群をビルド環境(ローカルネットワーク)に作成、起動
  - id: "INJECT"
    name: "gcr.io/$PROJECT_ID/cloud-builders/docker-compose"
    args: ["up", "-d"]
  # ベースとなるPythonイメージを用意してビルド時間を短縮
  # ビルド時間にこだわらないのであれば次のステップ[Build Image]と入れ替えて、イメージを呼び出してテストすればベースのメンテする手間は省ける
  - id: "TEST"
    name: "gcr.io/$PROJECT_ID/cloud-builders/pytest"
    args: ["pytest", "-v", "-s"]
    env:
      - DATABASE_USER=docker
      - DATABASE_NAME=docker
      - DATABASE_USER=docker
      - DATABASE_PASSWORD=docker
      - DATABASE_HOST=postgres
      - GS_PROJECT_ID=$PROJECT_ID
      - GS_BUCKET_NAME=$PROJECT_ID-$BRANCH_NAME
  # Container Registry(GCP)にイメージ作成
  - id: "BUILD"
    name: "gcr.io/kaniko-project/executor"
    args:
      - --destination=gcr.io/$PROJECT_ID/django-startproject/app:$COMMIT_SHA
  # CloudRunへデプロイ
  # - id: "DEPLOY"
  #   name: "gcr.io/cloud-builders/gcloud"
  #   args:
  #     - "beta"
  #     - "run"
  #     - "deploy"
  #     - "django-startproject"
  #     - "--allow-unauthenticated"
  #     - "--platform"
  #     - "managed"
  #     - "--project"
  #     - "$PROJECT_ID"
  #     - "--image"
  #     - "gcr.io/$PROJECT_ID/django-startproject/app:$COMMIT_SHA"
  #     - "--region"
  #     - "asia-northeast1"
# Buildのタイムアウト時間
timeout: 900s

このプロジェクトではPostgreSQLを採用しているので、簡単にテストを回そうとするとSQLiteへ置き換えれば依存関係を注入しなくとも実行できますが、DjangoではRDBで微妙に振る舞いが違ったり、独自のフィールドを持っていたりするのでおすすめできません。

便利なコミュニティビルダーを用意する

GoogleCloudPlatform/cloud-builders-community
Community-contributed images for Google Cloud Build - GoogleCloudPlatform/cloud-builders-community

ビルドを実行するdocker-composeはコミュニティで公開されているビルダーイメージなので、予め自分のGCPプロジェクトのContainerRegistryへ登録しておく必要があります。ここでは以下をレジストリに登録していますが、他にも便利なスラック通知などもあるのでローカルマシンにクローンして置いておくと、必要なときにgcloud buildで送信すれば使えるので便利です。

git clone https://github.com/GoogleCloudPlatform/cloud-builders-community
cd cloud-builders-community/docker-compose
gcloud builds submit --config cloudbuild.yaml .

# SLACK通知をcloud functionsなしで使いたい場合、以下もContainerRegistryに入れておいてください
cd ../cloud-builders-community/slackbot
gcloud builds submit --config cloudbuild.yaml .

e.g.
-----
__ksh__@macbook-pro slackbot % gcloud builds submit --config cloudbuild.yaml .
Creating temporary tarball archive of 16 file(s) totalling 106.7 KiB before compression.
Uploading tarball of [.] to [gs://loft-208723_cloudbuild/source/1584939012.7-1743de1fe7254fb1b787f32a8334119b.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/loft-208723/builds/41dace38-d9bb-4c66-aecf-43107c837616].
Logs are available at [https://console.cloud.google.com/cloud-build/builds/41dace38-d9bb-4c66-aecf-43107c837616?project=1041929286010].
-----

これで実行する環境が準備できたので、CloudBuildのコンソール画面からビルドのトリガーを作成しましょう。

トリガーを作成したら、一覧画面へ戻って直接トリガーを実行するか、Gitリポジトリへなにかコミットしましょう。

PostgreSQLへの名前解決がされていて、テストが実行されているのが確認できましたでしょうか。ベースとなるイメージを準備すればさらにビルドのステップを高速で行えるようになります。
ただし、コミット頻度が低い場合は多少ビルド時間が長くかかったとしても、イメージのメンテなしでビルドが機能するように書いたほうが便利ですし、私は粒度によって調整するほうがスマートだと思います🤔

CloudRunへのデプロイはコメントアウトを外せば可能ですが、CloudSQLへの接続、コンテナの環境変数設定を行わないとアプリが起動しません。
次回は最後となりますが、CloudRunでアプリを稼働、運用する方法について書きたいと思います。
ご拝読ありがとうございました。

関連記事

ポリシー

この記事のすべてまたは一部の複製は、著作権者の同意なしでは禁止されています。 引用については著者名と記事のURLが表示されている場合に限り認められます。