前回は モノレポ(mono repository)内でgoのmoduleを相対パスで利用する方法 という記事を書きましたが、今回はさらにモノレポで管理しているAppengineの複数のサービスをデプロイする方法になります。
なぜGAEのデプロイの記事が必要?
前回の記事を試した方がいるかいないかは不明ですが、モノレポ内でmodで依存を解決したものをデプロイした場合、modを利用したデプロイ(GO111MODULE=on)ではGCP上のCloudBuild上でコンパイル(依存の解決)を行うため、相対的に管理しているモジュールを取得することができないためエラーになり、デプロイが完了しません。
なので、今回はサンプルも作り、丁寧に説明したいと思います。 サンプルのソースコードはこちらになります。
https://github.com/chidakiyo/benkyo/tree/master/appengine-relative-mod
デプロイするために必要な設定2つ
- デプロイ時にはvendorモードでデプロイする
- デプロイする際にgo.modファイルが存在してはだめ
上記の2点の対策が必要です。
vendorモードでデプロイするとは?
普通にmodを利用したAppengineのデプロイは以下のようなコマンドを実行します。
GO111MODULE=on gcloud app deploy ./app.yaml
gcloudコマンドをmodで管理する GO111MODULE=on
という環境変数の元実行します。
先程の話のように、相対的にモジュールを管理している場合、この方法ではデプロイは失敗します
成功するためには
vendorモードでデプロイする必要があるため、以下のような手続きでコマンドを実行します。
GO111MODULE=on go mod vendor // vendorディレクトリを作成する GO111MODULE=off gcloud app deploy ./app.yaml // Appengineのデプロイを実行 rm -rf ./vendor // 一時的に作成したvendorディレクトリを削除する(optional)
つまり、デプロイの際に、vendorディレクトリ配下に相対的に管理しているモジュールのソースコードを持ってきて、 そのファイルごと依存としてGCP側のデプロイ用のCloudBuildにまるごと渡します。
もう一つの嬉しい作用として、vendorモードでデプロイするとGAEのデプロイが若干早くなるようです。
注意: この1点目だけではうまくいきません。
go.modファイルを除外する
デプロイする際に、デプロイするアプリケーションのディレクトリ内にgo.modファイルが存在する場合、 GO111MODULE=off
でデプロイしてもCloudBuild側でmodを利用した依存解決をしようとします。
そのため、glcoud app deployコマンドでgo.modファイルを持っていかないように .gloudignore
ファイル内に
go.mod
と記述します。 これでCloudBuildのデプロイプロセスではvendorモードとして動作し、Appengineへのデプロイが成功します。
参考まで
Github にモノレポで相対パスでmod管理し、かつ、Appengineにデプロイできる簡単なサンプルを作成してみました。