はじめに
先進サービス開発事業部の山岡です。
GAE/Goは1.6, 1,8, 1.9, 1.11, 1.12(beta)と随時新しいGolangバージョンに対応してきていますが、1.11からはGAEのバックエンドがgVisorベースの2nd Generationとなり大きな変更点が複数ありました。 *1 1.11ではまだ互換性を保っていますが、GAE付属のサービス(ex. Memcache, Search等々)は今後使えなくなるようなので今の内からどのような影響がありそうかを調べ把握しておく必要があるでしょう。
今回は実際に小規模なアプリを1.11にマイグレーションしようとしたら色々とトラブルが発生したのでその内容と対処法を書いておきます。
goappとappcfg.pyが使えない
今までGoogle Cloud SDKのGo拡張には goapp
が付属されてきていましたが1.11からはこれを使用することができないので検証用のローカルサーバーは dev_appserver.py
を使うようにしましょう(オプションは大体同じような雰囲気なので然程困らないと思います)。
また appcfg.py
についても使用することができず、これを実行しようとすると RuntimeError: The runtime: 'go111' is only supported with gcloud.
と怒られてしまいますので、デプロイは gcloud app deploy
を使う必要があります。
なおappcfg.pyと違い普通にデプロイするといきなりトラフィックまで切り替わってしまうので、必要に応じて --no-promote
を付けてデプロイまでで止めておきましょう。
app.yamlでのアクセス制御ができない
これまでは app.yaml
の handler
内に login:required
や login:admin
等と書いておくことで特定のURLに対しGoogleアカウントベースのアクセス制御をかけることができ大変便利でした。しかしこれも2nd Genからは廃止となり、しかも完全な互換サービスは今の所無いようです。
どう対処するかはアプリ側の要件に依存するかと思いますが、今回は知らない人が入れなければそれでいい程度の要件であったためBasic認証をかけることで対処しました。
2019/07/01訂正: 1.11は1stGen扱いとなりこの制約は無くなりました。gVisorベースで動いてはいるものの基本的に1.9と互換性がある形に戻されました。
appengine.NewContext() でpanicが起こる
ローカルサーバーを起動した後にアクセスすると appengine: NewContext passed an unknown http.Request
が発生する事象に見舞われました。
これに関しては原因は追求しきれなかったのですが google.golang.org/appengine
のバージョンを1.0から1.5に更新してみたところ解決することができました。
ローカルと実環境でワーキングディレクトリの位置が変わる
ローカルサーバーで動作確認をした後でGAE実環境にアップロードしたところなぜかスタティックなファイルへのアクセスで no such file or directory
が発生しました。
GCPUGのノウハウ集 *2 によるとローカルサーバーと実環境ではワーキングディレクトリの位置が異なるため発生する事象だそうです。
今回は go.mod
と main.go
をプロジェクトルートに置くように配置して対処しました。下記のように形だけのものにしたので既存のコードにはほぼ影響ありません。
package main import ( "github.com/org/project/app" ) func main() { app.Run() }
デプロイにCloud Buildの権限が必要
CircleCIから gcloud app deploy
をしたところ下記のようなエラーが発生しました。どうも裏側で透過的にCloud Buildを使用しているようで、それに関する権限が無いとデプロイに失敗します。サービスアカウントに Cloud Build Editor
の権限を付与することで無事にデプロイできるようになりました。
Beginning deployment of service [default]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 0 files to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. ERROR: (gcloud.app.deploy) Error Response: [13] Permission to create cloud build is denied. 'Cloud Build Editor' role is required for the deployment: https://cloud.google.com/cloud-build/docs/securing-builds/configure-access-control#permissions. make: *** [Makefile:15: deploy] Error 1 Exited with code 2
終わりに
今回マイグレーションしたWebアプリは小規模なものでしたが、知らないと面倒なところが多かったです。
移行先サービスが完全ではないので2nd Genに今すぐ全面対応するのは辛い場合が多いと思いますが、後方互換性が確保されているGAE/Go1.11へは早めに移行しておきその後ゆっくりと1st GenのAPIから脱却していくのが良さそうです。
*1:2019/04/26 訂正:1st Genのままが正しいです。訂正記事
*2:gcpug/nouhau App Engine Standard Go 1.9 migration to Go 1.11 Working DirがLocalとProductionで変わる