Heroku で Haskell (Scotty + Persistent)

Heroku がすごいことを知ったので少しずつ使おうとしています。 で、 Haskell で書いたアプリケーションを動かそうとしているのですが、 ちょいちょい触りつつわかったことを書いてみます。

巷では Heroku で Haskell を動かすにはビルド済みのバイナリを push するのが よく知られた方法のようです。

しかしこの方法は Heroku の Celadon Cedar stack が Ubuntu 10.04 64bit であることを前提としていて、少し考えるとわかるように次のような問題があります。

  1. ローカルで Ubuntu 10.04 64bit を用意しなければならない
  2. Cedar stack が別のディストリビューションを使うようになったら 追従しなければならない

で、そうでなくて Heroku 上でビルドする方法はないのかと探したら少し前に xuwei さんが Haskell 用の buildpack を使う方法を書いていました。 ここで紹介されているリポジトリに書いてある通りにやってみると すごく簡単にアプリケーションを動かすことができます。

というわけで、この buildpack を使って 遊んでみた感じのまとめとして、 Scotty + Persistent で簡単なアプリケーションを作ってみました。

ページにアクセスするとフォームが現れて、そこから post された文字列を DB に格納して、 DB にある内容を表示するというまあごくシンプルなやつです。 使い方とかは README に書いてあるので読んでください。

テンプレートエンジンは少し探してみたのですがなんか定番っぽいのがなさそうで、 fujimura さんの書いている Mustache (hastache) を使ってみました。

Heroku の無料アカウントで標準の PostgreSQL を使うことになります。 Mac の Homebrew で何も考えずに PostgreSQL をインストールすると 32bit 版がインストールされますが、 これを使うと persistent-postgresql のビルドでこけます。 まあその辺直すのめんどくさそうだったので、ローカルでは SQLite を使い、 Heroku 上では PostgreSQL を使うということができるように してみました。 PostgreSQL をインストールしていない環境で動かすには src/DBUtil.hs#define SQLite の行をアンコメントし、 scotty-on-heroku.cabalpersistent-postgresql の行をコメントアウトしてください。

ちなみに Yesod アプリケーションも同じ方法で作ってみようとしたのですが、 どうやら Heroku では push 時に走るビルドが 15 分かかると殺されてしまう仕様のようです。 (公式ドキュメントに見当たらない・・) 15 分では Yesod を最初からビルドすることはできないのでこの方法では無理です。 Yesod に限らずとも大きなアプリケーションを動かすときは ビルド済みのバイナリを push という方法しかなさそうです。