GAE/Go1.11のランタイムを実際にデプロイまでしてみましたよっていう内容です。
準備
ディレクトリ構成
以下のようなディレクトリ構成でプロジェクトを作成しました。
$GOPATH
└── src
├── app
│ ├── app.yaml
│ └── main.go
└── handler
├── index.go
└── init.go
server準備
GAE/Go1.11からは標準の net/http
パッケージが使えますので、http.ListenAndServe
で簡単なweb server を書きます。
routerの実装
// app/main.go import ( "fmt" "log" "net/http" "os" "handler" ) func main() { mux := http.NewServeMux() mux.HandleFunc("/", handler.Index) port := os.Getenv("PORT") if port == "" { port = "8080" log.Printf("Defaulting to port %s", port) } if err := http.ListenAndServe(fmt.Sprintf(":%s", port), mux); err != nil { panic(err) } }
※ main.goでportを環境変数から取り出してますが、この PORT
はAppEngineのデフォルトで指定されてるものなのでこのまま使えます。
handlerの実装
// handler/index.go // Index ... func Index(w http.ResponseWriter,r *http.Request){ if r.URL.Path != "/" { http.NotFound(w,r) return } w.WriteHeader(http.StatusOK) if _, err := w.Write([]byte("hello appengine go1.11 world!!!")); err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } }
local で起動
goapp serve app.yaml
が使えなくなっていたので、gcloud component の中に入ってくる dev_appserver.py
を使います。
※ 事前に dev_appserver.py
を gcloud コマンドでinstall -> pathを通しておくといいです。
$ dev_appserver.py src/app/app.yaml INFO 2018-10-28 11:25:04,061 devappserver2.py:278] Skipping SDK update check. INFO 2018-10-28 11:25:04,213 api_server.py:275] Starting API server at: http://localhost:64860 INFO 2018-10-28 11:25:04,281 dispatcher.py:270] Starting module "default" running at: http://localhost:8080 INFO 2018-10-28 11:25:04,283 admin_server.py:152] Starting admin server at: http://localhost:8000
local packageの初期化
main package以外の各パッケージも main
で初期化するものかと思ってましたが、init
で初期化できました。
各packegeで初期化時に行いたい処理を各場合は init
に書けば良さそうです。
// handler/init.go func init(){ // sample的に log とconsoleに出力させる。 log.Printf("init") }
Deploy
appcfg
およびそのラッパーコマンドである goapp
が使えなくなり gcloud app deploy
のみしか使えなくなっていますのでこちらのコマンドでデプロイを行います。
事前にdeploy対象のプロジェクトにログインをしておきます。
$ gcloud auth login
Deploy準備
デプロイ前に以下のファイルを設定します。
- setting app.yaml
- setting .gcloudignore
setting app.yaml
app.yaml Configuration File | App Engine standard environment for Go 1.11 docs | Google Cloud を参考にするといいです。
基本はruntimeとservice名だけ入れておくとdeploy時に自動でどのサービスにデプロイするのか解釈してくれるので便利です。
runtime: go111 service: YOUR-SERVICE-NAME
setting .gcloudignore
gcloud app deploy
を使う場合、従来の skip_files は使えず、deploy時にアップロードしたくないファイル群は .gcloudignore
ファイルを使って管理します。
Deploy
$ gcloud app deploy --project [YOUR_PROJETCT_ID] --version [VESRION_NAME] Services to deploy: descriptor: [~/emahiro/path/gae_go111_app/src/app/app.yaml] source: [~/emahiro/pagh/gae_go111_app/src/app] target project: [dena-opfsys-gcp] target service: [gae-go111-app] target version: [VESRION_NAME] target url: [https://gae-go111-app-[YOUR_PROJETCT_ID].appspot.com] Do you want to continue (Y/n)? Y Beginning deployment of service [gae-go111-app]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 1 file to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ # 略
deployはmoduleで変更があった場合などアップロードする対象が増える、差分アップロードっぽいです。
まとめ
とりあえず起動してdeployするところまでざっくり試してみました。
loggingやdatastoreあたりのライブラリの動作を検証してみようと思います。特に cloud.golang.org/appengine
のpackageが使えなくなるのでその代替となる golang.google.com/go
あたりを使うところは確認してみたいです。
また、実際にどうライブラリをinstallしてpackageを取り込んでくれるのか、go.modあたりも使ってみようと思います。