LoginSignup
30
23

More than 5 years have passed since last update.

GAE/Goでのアプリの組み方

Last updated at Posted at 2017-05-10

GoもGAEも不慣れな状態でやってみたら、タイミングもあって色々ハマったのでまとめました。
マサカリやもっといい方法があればぜひコメントください。

変更履歴

  • ※Go1.8に対応

目的

  • GAEのアプリをリリースしたい
  • テストも書きたい
  • ローカルでの動作確認もしたい
  • 外部ライブラリ使いたい
  • DataStoreやQueueを使いたい

環境

  • GAE/Go standard environment (go1.8.3)
  • Google Cloud SDK 167.0.0
    • app-engine-go

サンプルのソースコードはこちら。
https://github.com/uryyyyyyy/GAESample

GAEアプリのディレクトリ構成

ディレクトリ構成

色々悩んだ結果こうなりました。

$ tree .
.
├── app
│   ├── gae_service1
│   │   ├── local.yaml
│   │   ├── main.go
│   │   └── prod.yaml # stg.yamlも必要があれば
│   ├── gae_service2
│   │   ├── local.yaml
│   │   ├── main.go
│   │   └── prod.yaml
│   └── other_application # GAE以外にgoアプリがあれば
│       └── main.go
├── bin # GAE以外のアプリのバイナリ置き場など
├── commands # 各種コマンド置き場
├── src # 自分で書いたコード
│   ├── gae_service1 # 各サービスでのみ使うコードとか
│   ├── gae_service2
│   ├── other_application
│   └── utils # 共有したいコードとか
└── vendor
    ├── glide.lock
    └── glide.yaml

Commands

Makefileは個人的に使いにくかったのでshellベースにして、commandsフォルダ以下に置きました。

処理内容はお好みですが、共通部分としてGOROOT、GOPATHなどの設定をしています。

export GOROOT=$(dirname $(which dev_appserver.py))/../platform/google_appengine/goroot-1.8
export GOPATH=`pwd`:`pwd`/vendor
export GAE_ROOTDIR=`pwd`

GOROOTは見ての通りで、GAEでの動作環境に合わせています。
GOPATHは、src以下を入れるのは良いとして、vendorを普通のGoアプリのようにsrc直下に置くと gocloud app deploy コマンドがうまく動かないためワークアラウンドとして避けています。いいやり方があれば知りたい。

コマンドの具体的な内容としては、例えば

  • ローカルでのGAEアプリのrun(必要に応じて複数立ち上げたりcronも入れたりする)
  • deployコマンド(バージョニングや)

などがあります。いずれも記述量は少ないものの、たまに気をつけることがあるのでshell化しています。詳しくはサンプルを見てください。

なぜこうなったのか

vendorについて

前述したとおり、GAEにはvendorの考慮がされていないようで、普通にvendor以下に置いてしまうとデプロイがうまくいかなかったりが頻発しました。
goapp コマンドを使ったり nobuild_files の記述で回避できているケースもあるようですが、面倒なのでフォルダを別で管理してGOPATHに追加することで誤魔化しています。

また、GCPUGで聞いた所、 appengine パッケージでなく、 google.golang.org/appengine を使うことが推奨されているようなので、glideなどで管理しつつなるべく最新に追従させるようにしています。
(今後go1.8が正式対応するにあたり、context周りで破壊的変更が入るだろうとのことでした。)

appディレクトリについて

GAEへのデプロイをする際に、普通にsrc以下にエントリのファイルを置くと、ビルド時になぜかファイルが重複してアップロードされるようでエラーになります。
エントリポイントとその他ファイルを別ディレクトリに置くと上記問題が解消されるとの記事を見かけたので、そのように対応しています。

app.yaml(local.yaml / prod.yaml)について

GAEでは、各種設定をyamlファイルで記述することになっています。
デフォルトではapp.yamlが読まれるのですが、環境毎に設定を分けたい場合は任意のファイル名にできます。
例えば、localでは外部サーバーへのアクセスはしてほしくない、ログをたくさん吐きたい、という場合のために、各環境毎に環境変数を変えたyamlを用意しています。

また、複数のGAEアプリケーションを立ち上げることはよくあると思うので、service名を付けて区別するようにします。

GAEへのデプロイ

gcloudではデフォルトでは日時でバージョンが振られます。
これだけではどの状態のアプリをリリースしたのかわからないので、git hashをversionに含めるようにしています。

testやlintについて

特に気にせず書けています。
goのappengineのコードでのテストの書き方はまた別の機会に書きます。

30
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
23