HerokuにGroongaはインストールされていないので、HerokuでGroongaを使うためにはGroongaをビルドしなければいけません。今回はHerokuでGroongaをビルドする方法を説明します。
buildpack
Herokuにインストールされていないソフトウェアを使えるようにする仕組みがbuildpackです。GroongaはHerokuにインストールされていないソフトウェアなので、buildpackの仕組みに従う必要があります。
buildpackの作り方
buildpackの仕組みに従うには次の作業が必要です。
-
Heroku上でGroongaをビルドする。
-
ビルドしたGroongaをダウンロードできる場所にアップロードする。
-
ビルドしたGroongaをダウンロードしてセットアップするbuildpackを作る。
-
作ったbuildpackをリリースする。
順に説明します。
Heroku上でGroongaをビルドしてアップロード
まず、次の2つを一緒に説明します。詳細は後述しますが、同じ処理の単位で実行しなければいけないからです。
-
Heroku上でGroongaをビルドする。
-
ビルドしたGroongaをダウンロードできる場所にアップロードする。
この2つを実現するビルド用のHerokuアプリケーションを作ります。Groongaの場合はheroku-groonga-builderというのがそれです。
このHerokuアプリケーションは次のことをします。
-
Groongaのソースをダウンロード
-
Groongaをビルド
-
ビルドしたGroongaをアーカイブ
-
アーカイブしたGroongaをアップロード
heroku-groonga-builderは何もしないRackアプリケーション(config.ru
を置いているだけ)で、実際の処理はRakefileの中に書いています。
ソースのダウンロード、ビルド、アーカイブの処理は次のようなイメージです。
% curl -O http://packages.groonga.org/source/groonga/groonga-4.0.2.tar.gz
% tar xf groonga-4.0.2.tar.gz
% cd groonga-4.0.2
% ./configure --prefix=$HOME/vendor/groonga
% make
% make install
% cd -
% tar cJf heroku-groonga-4.0.2.tar.xz vendor/groonga
実際は次のようにrake
を実行して↑の処理を実施しています1。
% heroku run:detached rake
detachedを使っているのは、Groongaのビルドにとても時間がかかるからです。だいたい6時間くらいかかります2。
アーカイブしたGroongaは同じプロセス内でアップロードする必要があります。なぜなら、プロセスが終了するとビルドしたアーカイブも消えるからです。これが後述すると書いていた同じ処理で実行しなければいけない理由です。
アーカイブしたGroongaはGitHubのreleaseページにアップロードしています。例えば、Groonga 4.0.2の場合は次のページです。
Heroku上からアップロードするのでGitHubにアクセスするためのAPIキーをHerokuアプリケーションに渡さないといけません。APIキーはセキュリティー上で重要な値です。heroku-groonga-builderではこの情報を環境変数で渡しています。環境変数名はGITHUB_TOKEN
です。
環境変数で渡すには次の2つの方法があります。
heroku config:set GITHUB_TOKEN=xxx
heroku run:detached rake GITHUB_TOKEN=xxx
前者はHerokuの仕組みを使って設定する方法で、後者はRakeの仕組みを使って設定する方法です。前者はheroku config:get GITHUB_TOKEN
で、後者はheroku ps
で後から値を確認できるので、安全性という面ではどっちもどっちです。毎回新しいAPIキーを生成してそれを使い、ビルドが終わったら破棄するくらいがよいのではないかという案がありますが、実装はしていません。
APIキーを使ってアップロードする方法にはいくつかあります。Go言語で書かれたgithub-releaseというツールを使う方法や、Octokitなどのライブラリーを使う方法です。
heroku-groonga-builderは以前はgithub-releaseを使っていましたが、今はOctokitを使っています。
ダウンロードしてセットアップ
HerokuでビルドしたGroongaができたのでそれを使ってHerokuアプリケーション用の環境をセットアップします。これをするモジュールがheroku-buildpack-groongaです。これはbuildpackの一種です。
実はheroku-buildpack-groongaの中でGroongaをビルドするという選択肢もあるのですが、そうするとgit push heroku master
する毎にGroongaのビルドのために6時間くらいかかるので現実的ではありません。ビルド済みのGroongaをダウンロードすることで時間を短縮しています。
buildpackは次の3つのプログラムが必須です。すべて新規で実装します。実行ファイルになっていれば実装言語は問いません。bashで実装してもRubyで実装しても構いません。
bin/detect
bin/compile
bin/release
bin/detect
は、このbuildpackを使おうとしているHerokuアプリケーションがこのbuildpackが要求する事前条件を満たしているかをチェックします。例えば、Rubyのbuildpackは「Gemfile
が存在すること」が事前条件で、heroku-buildpack-groongaは「groonga/
ディレクトリーが存在すること」が事前条件です。
bin/compile
は、Herokuアプリケーションが必要なソフトウェアをインストールします。例えば、heroku-buildpack-groongaならアーカイブを展開します。
bin/release
は、Herokuアプリケーションが使うデフォルトの設定を返します。例えば、環境変数だったりサービスを起動するコマンドラインなどの設定を返します。heroku-buildpack-groongaは環境変数PATH
の設定などを返します。
詳細は公式サイトのドキュメントやheroku-buildpack-groongaの実装を参照してください。なお、heroku-buildpack-groongaはRubyで実装しています。
buildpackの動作確認用Herokuアプリケーションがあると便利です。heroku-buildpack-groongaを使ったHerokuアプリケーションは次のコマンドで作成できます。
% heroku apps:create --buildpack https://github.com/groonga/heroku-buildpack-groonga
buildpackを修正した場合はHerokuアプリケーションをgit push heroku master
してください。heroku ps:restart
では新しいbuildpackは動きません。既存のbuildpack実行結果を再利用します。
buildpackをリリース
buildpackが動くようになったらリリースします。リリース用のプラグインがあるのでインストールします。
% heroku plugins:install https://github.com/heroku/heroku-buildpacks
これでheroku buildpacks:publish
が使えるようになります。buildpacks:publish
時に指定する名前は#{グループ}/#{名前}
とする習慣があるようなので、heroku-buildpack-groongaはgroonga/groonga
を使っています。
% heroku buildpacks:publish groonga/groonga
これでbuildpackをS3からダウンロードできるようになります。URLは次のようになります。
https://codon-buildpacks.s3.amazonaws.com/buildpacks/#{グループ}/#{名前}.tgz
例えば、groonga/groonga
ならこうなります。
https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz
ユーザーにはS3からダウンロードしてもらうようにしましょう。
まとめ
Heroku用Groongaのビルド方法を説明しました。ビルドするには次の4つの手順があります。
-
Heroku上でGroongaをビルドする。
-
ビルドしたGroongaをダウンロードできる場所にアップロードする。
-
ビルドしたGroongaをダウンロードしてセットアップするbuildpackを作る。
-
作ったbuildpackをリリースする。
このうち、前半の2つがheroku-groonga-builderで実施していることで、後半の2つがheroku-buildpack-groongaが実施していることです。
HerokuにインストールされていないソフトウェアをHerokuで使えるようにしたいときの参考にしてください。
おまけ: heroku-buildpack-rroonga
おまけで、Rroonga用のbuildpackであるheroku-buildpack-rroongaの作り方についても簡単に説明します。
このbuildpackはGroongaのbuildpackとRubyのbuildpackを一緒に使います。次のようなイメージです。
bin/detect
が呼ばれたとき- GroongaのbuildpackとRroongaのbuildpackの
bin/detect
相当の処理をする
- GroongaのbuildpackとRroongaのbuildpackの
bin/compile
が呼ばれたとき- GroongaのbuildpackとRroongaのbuildpackをダウンロード
- それぞれの
bin/compile
を実行 - それぞれの
bin/release
も実行して結果をマージして保存
bin/release
が呼ばれたときbin/compile
のときに保存したbin/release
をマージした結果をそのまま出力
関連記事: HerokuでRroongaを使う方法