App Engineのgo111用ディレクトリ構成
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