Go言語を書く際、成果物がシングルバイナリになるのは便利です。deployするときや他人に使ってもらうときに、それだけ渡せば使ってもらえるので。cliツールやapiサーバーを書くときにはこの方式で困っていなかったのですが、いわゆるWebアプリをGo言語で書くときのベストプラックティスが分からなかったのでエントリにしておきます。
前提
- Go言語側は重厚なフレームワークは特に使わない
net/http
やhtml/template
といった標準ライブラリを使う
- フロント側はVue.js
シングルバイナリを作るまでの過程
以下の過程をMakefile
に書いてmake build
とやってシングルバイナリを作っていました。
- webpackでJavaScript関係を
bundle.js
という感じで一つのファイルにまとめる go-assets-builder
を使って、index.html
やbundle.js
を一つのasset(asset.goみたいなのができる)にまとめる- 全てgoのファイルになったので、
go build
でシングルバイナリに固める
シングルバイナリがすぐできるならば問題ないですが、自然言語処理を内部で使っているアプリケーションのため、成果物が70Mb以上のサイズになります(kagomeを使わせてもらっています)。htmlやjsをちょっと変えて確認したいだけなのに、make build
で20秒くらいかかるのはなかなかストレスですね。なんとかしたい。ちなみにファイルに変更があったら自動でmake build
するには、reflexなどのファイル変更を監視する系のツールを使うといいというのを教えてもらいました。
解決案1: ローカルと本番で処理を分ける
ローカルではindex.html
やbundle.js
を呼ばれる度に静的ファイルを読み込むということをすれば、テンプレートが書き換えられる度にシングルバイナリを作りなおす必要はなくなります。本番環境ではさきほどまでに述べた方法で全部goのファイルにしてシングルバイナリを作ります。
問題自体は解決しますが、localと本番で処理を分岐するのは考えることも増えるし、コードも増えるのでちょっとイマイチですね...。
解決案2: 静的ファイルはNginxで返すようにして、アプリケーションサーバーはAPIサーバーの役割に徹する
自分はこれを選択しました。SPAになっているので、index.html
とbundle.js
はNginxで返します。Vue.jsから叩かれるエンドポイントはgoがAPIサーバーっぽく処理させます。Nginxの設定ファイルだとこんな感じ。
upstream local-backend {
server localhost:7778; # goのアプリケーションサーバーです
}
server {
listen 7777 default_server;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
location / {
root /www/app;
}
location /api {
proxy_pass http://local-backend;
}
}
手元でNginxを立てるのは面倒なので、その場合はwebpackの機能を使います。webpack.config.js
に以下のように書くと、特定のpath以下だとapiサーバーにリクエストをproxyしてくれます。webpack便利やん。
module.exports = { entry: './src/js/app', output: { path: __dirname + '/static', filename: 'bundle.js' }, ..., devServer: { host: 'localhost', port: 7777, contentBase: __dirname + '/static', proxy: { '/api': { target: 'http://localhost:7778' } } } };
これでhtmlやjsを書き換えただけなのにシングルバイナリ作りが始まってなかなか修正された様子が見れない、といったことがなくなりました。やったー。全体の様子はこの辺です。Webサイト自体はこちらです。
Goの変数でテンプレートを出し分けなどをやりたい場合、素のhtmlでない場合が多いのでこのパターンは使えないというのが悩ましいですね。
まとめ
Go言語でWebアプリケーションを書くときにオートリロードをするときに困ったこと、自分なりの解決策を書いてみました。もっといい方法がある!!という方は是非教えてください。
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: Kindle版
- この商品を含むブログを見る