go+ginでローカルで作ったWebアプリをGoogleAppEngineに載せる時に注意することまとめ

この記事は最終更新日から3年以上が経過しています。

本記事について

Golang+ginでローカルで作ったWebアプリをGoogleAppEngineに載せる時にいろいろハマったのでその注意点をまとめます。
メモ書きです。

Golang+ginでローカルで作ったWebアプリ

ユーザの要求に合わせてデータベースからデータを引っ張ってきて表示するよくあるWebサイトです。

https://github.com/notvitor/go-gin-boilerplate
の上に、DB接続やらHTTPリクエストの処理やらセッション管理をするGolangコードを別ファイルに作って参照しています。

MyProject以下に
server.go
app.yaml
dbフォルダ(CloudSQLを操作するためのGoソースが入ってる)
sessionフォルダ(セッション管理をするためのGoソースが入ってる)
requestフォルダ(HTTPリクエストを処理するためのGoソースが入ってる)
templatesフォルダ(HTMLがいっぱい入ってる)
publicフォルダ(jsが入ってる)

import (
    "github.com/gin-gonic/gin"
    "github.com/gin-gonic/contrib/sessions"

    "MyProject/request"
    "MyProject/db"
    "MyProject/session"
     "fmt"
     "strconv"
)

Go+ginで作ったWebアプリをデプロイする記事は大抵Golangソース単体をデプロイする簡単なものだけだったのでGolangソースが複数あるものについて言及していきたいと思います。

デプロイする時のPermissionエラー

goapp deploy プロジェクトフォルダ

を最初使っていましたが、

[Google App Engine]You do not have permission to modify this app

というエラーが出てだいぶ困りました。そんな時以下のサイトを見つけました。

http://deferloader.blog.uhuru.co.jp/?p=1309

同じソースコードをapp.yamlのapplication: だけ変更して違うアプリケーションIDのところへデプロイしようとした時によく出ます。これ実はappcfg.pyがcookieを利用して前回入力したアカウントを記憶しているので、cookieに保存されているアプリケーションIDとapp.yamlに記述されたアプリケーションIDが異なっていることが原因です。

なので、このエラーが出たらアカウントが違うかCookieに違うものが保存されているのか、その両方かも。
ということで、アカウントが正しいことを確認した後

appcfg.py -A [GAEに作ったプロジェクトのID] -V v1 update --no_cookies  [デプロイしたいファイル群のディレクトリパス]

を叩いてデプロイしたほうが、Cookieがどうのこうのに煩わされることがないと思います。

Failed parsing input: app file hoge.go conflicts with same file imported from GOPATH

これの解決策を見つけるのも大変でした。

http://otiai10.hatenablog.com/entry/2016/05/08/022515

appengineによるimportと、そこでimportされたソースコードによるimport(自分のケースだとmain.goがimportしてる)が、同じファイルをimportしようとしているっぽい。

ということですね。
僕もこのエラーが出た時に$GOPATH以下のProjectに対してデプロイしようとしてました。
(まぁローカルで動作確認したものをデプロイするわけだし、何も知らないと必ず1回はこのエラーに出くわすと思う)

解決策:

プロジェクト自体をコピーしてそのフォルダに対してappcfg.pyでデプロイしました。
$GOPATH/src/以下に作ってあったプロジェクトフォルダをコピーして、~/temp/以下に置いて

appcfg.py -A [GAEに作ったプロジェクトのID] -V v1 update --no_cookies  ~/temp/MyProject

みたいな感じですね。

ただ、これだいぶクセがあって、デプロイ結果には
~temp/MyProjectの:
server.go、app.yaml、HTMLテンプレート、JSファイル

$GOPATH/src/MyProjectの
server.goで参照したgoファイル

というようにファイルの種類によってデプロイされるもののパスが違ってきます。
これは気をつけたほうがよいですね。
appengineによるimportがされてるから仕方ないのかなと自分を無理やり納得させていますが、中々気づけませんでした。

GAEにデプロイする前に

goapp serve [プロジェクトディレクトリ]

でやってみてもしローカル上で動くようなら、デプロイの仕方を間違えなければGAEでも動くと思います。
(ソースはなくて、経験則です。)


CloudSQLをdbrで、GAEで使うときに注意すること

世間ではdbrを使ってCloudSQLを叩く人があまりいなくてちょっと苦労しました。

CloudSQLの設定
Google Cloud SQL初期設定
http://java.sakura.ne.jp/base/page-287

Google Cloud SQL外部からの接続設定 アクセス許可
http://java.sakura.ne.jp/base/page-302

dbrに関しては↓を見ると良いと思います。
dbr – Go 言語 O/R Mapper の紹介
https://eurie.co.jp/blog/engineering/2015/12/go-lang-ormapper-dbr

ローカルのMySQLサーバにアクセスする時

masterConnection, _ = dbr.Open("mysql", "root:@tcp(127.0.0.1:3306)/DBName", nil)
masterDBSession = masterConnection.NewSession(nil)

でDBに接続するセッションができます。(MySQLサーバは既に立っている前提です。)
これを使って普段は

var u DBUsers
sess.Select("*").From("users").Where("id = ?", id).Load(&u)

という感じのコードでMySQLからデータを取ってくるなどします。

(非推奨)CloudSQLにIPアドレス直書きでアクセス

conn, _ = dbr.Open("mysql", "ユーザ名:パスワード@tcp(IPv4アドレス/DBName", nil)
sess = conn.NewSession(nil)

何故非推奨なのかというと、IPアドレス経由でアクセスするとものすごく遅いからです。
普通のアプリとしては使い物にならないレベルですが、適当にダミーデータなどを入れておきたいなと思った時にはこの方法で少しInsertしたりUpdateしたりはしました。

それとローカルからgo+dbrでCloudSQLにアクセスするにはこうするしかないきがするのでローカルでCloudSQLの動作を見たいならこれを使いましょう。

参考:http://otiai10.hatenablog.com/entry/2016/04/03/054116

本番は動くがローカルで動かない。なぜなら、ローカルのDev Serverには環境変数を直接渡せないようだ。

GAE上からCloudSQLにアクセス

dbr.Open("mysql","root@cloudsql(プロジェクト名:インスタンス名)/(DB名)",nil)
sess = conn.NewSession(nil);

GAEにデプロイしたらこの方法を取る。IPアドレスでアクセスしてた時が嘘のように早く動く。
ただこの記法はGAEにデプロイしたWebアプリからアクセスする時用なので、ローカルでこれを動かしてもCloudSQLにアクセスはできません。

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント
この記事にコメントはありません。
あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした