App Engine Standard EnvironmentでGo1.9を使う時は以下のように、リポジトリのルートをGOPATHとして設定し、appcfg.pyを使ってデプロイをしていました。
.
├── app.yaml
└── src
└── app
├── glide.lock
├── glide.yaml
├── app.go
├── handler
├── ...
└── vendor
- app.go
package app import ( "net/http" "app/handler" ) func init() { http.Handle("/", handler.New()) }
これがgo111のランタイムになると、main関数が必須になり、デプロイコマンドもgcloud app deployに変わります。*1
そのため、以下の条件を満たしつつ、どのようなディレクトリ構成にするのが良いのか考えてみました。
app.yamlのパスは変更しないGOPATHをリポジトリごとに変更しなくても良いようにするsrc/appはpkgに変更app.goはpkg.goに変更
- 依存関係の管理に
go.modを使う- リポジトリのルートに配置
1) ./main.goを作成する
.
├── app.yaml
├── go.mod
├── go.sum
├── main.go
└── pkg
├── handler
├── ...
└── pkg.go
2) ./cmd/app/main.goを作成し、app.yamlのmainでパスを指定する
.
├── app.yaml
├── cmd
│ └── app
│ └── main.go
├── go.mod
├── go.sum
└── pkg
├── handler
├── ...
└── pkg.go
この時、プライベートなパッケージ*2を使っているとCloud Buildで依存関係を解決できません。
対策としては、代わりにvendorを使う、もしくはgo.modのreplaceディレクティブを使う、のどちらかです。
しかし、vendorを使う場合にはgo.modを.gcloudignoreに追加し、GO111MODULEをoffにしないといけません。
また、go.modを使うにはGO111MODULEをonにしないといけません。
GO111MODULEはリポジトリをGOPATHの配下に置くか、外に置かでautoの時の値が変わるため*3、組み合わせが非常に複雑です。
まとめると次のようになります。
| 依存管理 | リポジトリの場所 | GO111MODULE | デプロイ可否 |
|---|---|---|---|
| go.mod | GOPATH配下 | auto(=off) | offだと使用不可 |
| go.mod | GOPATH配下 | on | OK |
| go.mod | GOPATH外 | auto(=on) | OK |
| go.mod | GOPATH外 | off | offにできない |
| vendor | GOPATH配下 | auto(=off) | 1)はOK、2)はNG |
| vendor | GOPATH配下 | on | NG |
| vendor | GOPATH外 | auto(=on) | NG |
| vendor | GOPATH外 | off | offにできない |
※確認する際にCloud Buildで使われたイメージはgcr.io/gae-runtimes/go111_app_builder:go111_20190503_1_11_9_RC00です
正しくgo.modを使えば問題なくデプロイできるため、replace対象のパッケージが管理できるのであればこちらを使うのが良さそうです。
ただ、replace対象のパッケージはgitのsubmodulesやsubtreeで管理することになり、それが煩雑になってしまう可能性があります。
そういった場合、現段階だと1)をGOPATH配下に置くのが無難です。
app.yamlでmainを指定することができませんが、今のプロジェクトでは必要なかったので以下のディレクトリ構成にすることにしました。
. ├── app.yaml ├── go.mod // デプロイしない ├── go.sum // デプロイしない ├── main.go ├── pkg │ ├── handler │ ├── ... │ └── pkg.go └── vendor // `GO111MODULE=on go mod vendor` で作成
*1:https://cloud.google.com/appengine/docs/standard/go111/go-differences 参照
*3:GOPATH配下: off、GOPATH外: on