Try Golang! Google App Engineへのデプロイ時にvendorで困った話

Be careful when deploying Golang app with vendor to GAE.

Takuo
VELTRA Engineering
7 min readOct 18, 2017

--

Google App Engine(以下、GAE)にGoのアプリケーションをデプロイする際、サードパーティ製のパッケージをvendorに格納してデプロイを実施したら、エラーが発生しまくった時の話です。ちなみに、今回組込むパッケージは、Echo 3.2.3。こちらはGo 1.8の環境で動くので、GAEのbeta環境を使用しています。

そもそもGoのvendorって?

Goにおける一般的なサードパーティ製パッケージの取得方法はgo getです。ただこの方法では、パッケージはGOPATH配下に格納されるため、複数のプロジェクトを開発する際に制約が生まれてしまいます。そこでGo 1.5から登場したのがvendoringで、vendorという名前のディレクトリにパッケージを格納することで、プロジェクト毎に依存パッケージのバージョンを管理することができるようになりました。

GAEへのデプロイ時にエラーが発生!

ところが、このvendoringを利用したプロジェクトをGAEにデプロイしようとすると、エラーが発生してしまいます。dev_appserver.pyを使用したローカル実行ではうまくいくのに!

実際にエラーを発生させたモジュール構成はこんな感じ。GOPATHを空にしてEchoをgo getしたものを、vendorに移動しただけです。Echoが参照しているパッケージがいくつかあるので、vendor配下は少し複雑です。

GAEへのデプロイ時に発生したエラーはこんな感じ。そもそもEcho本体すら見つけることができません。

エラーを解消してデプロイリベンジ!

  • 対策その1
    実はGAEのデプロイでimport文を解決する際、参照するディレクトリに vendorは含まれていません。含まれるのは「app.yamlを格納しているディレクトリとその配下」と「GOPATH以下」の2つ。ということで、ひとまずvendoringをやめて通常のGOPATHでやってみましょう。

むむむ。Echoは見つかったようですが、別のパッケージが見つからないと怒られましたね。

  • 対策その2
    上のエラーは、valyala/fasttemplateパッケージ内でvendorが利用されており、ここに格納されているvalyala/bytebufferpoolが見つけられなかったために起きています。ということで、見つけられなかったモジュールは自前でgo getしましょう。

うーむ。パッケージはすべて見つかったようですが、コンパイルができないとな。

  • 対策その3
    自前でgo getしたモジュールと、もともとvendor内にあったモジュールで競合が起きているので、vendor内のモジュールは削除してしまいましょう。これで、GAEへのデプロイができるようになりました!

手動でパッケージ管理なんてやってられない!

正直、上の作業を毎回するのは大変!それに結局グローバルなGOPATHを使っているので、プロジェクト毎の管理ができていません。ということで、これらを解消するために、GlideというGoのパッケージ管理ツールとシンボリックリンクを使用します。

  • Goのパッケージ管理ツール Glide
    go getの代わりに下のコマンドを実行することで、依存パッケージ内のvendorを解決しながら、vendoring構成に基づいてパッケージをダウンロードしてくれます。また、パッケージ内のvendorディレクトリの削除もしてくれます。
  • シンボリックリンクなGOPATH
    GlideだけではGAEへのデプロイでエラーが発生するので、いっそのことデプロイ時だけ、GOPATHを変更してしまいましょう。ただvendorの下には、GOPATHの下にあるsrcディレクトリがないので、以下のようにシンボリックリンクを使います。

GAEへのデプロイ時のみ、GOPATHを(project root)/gopathに書き換えて実行してあげればうまくいきます。

ここまで書いてあれですが、GAEのデプロイ時もvendoringルールに則って解決してくれれば、こんな面倒くさいことはしなくて済むんですよね。Google Cloud SDKの今後の改善に期待しましょう!

以下は、大変参考にさせていただいたサイトです。

--

--

Takuo
VELTRA Engineering

Engineer who likes travel, simple code, and something new