読者です 読者をやめる 読者になる 読者になる

taketoncheir.log

Like the Decatoncheir by Poseidon Industrial, This blog is Yet Another Storage for My Long Term Memories.

Yesod1.1 on Heroku

YesodアプリをHerokuにdeployする

2012年8月13日23時17分、HerokuにYesodアプリをdeployすることに成功しました。
作業において、@thimuraさんのブログこちらの記事を参考にしました。
今回の作業内容をメモっておきます。

今回のレシピ

  • Ubuntu10.04LTS-64bit
  • ghc-7.4.1
  • Haskell-platform-2012.2.0.0-64bit
  • Yesod-1.1
  • cabal-dev
  • heroku-toolbelt

構築方法

まずはUbuntu10.04LTS-64bitを用意

@thimuraさんも言及されていますが、最終的に詰まる部分はlibgmpやlibffiなどの共有ライブラリがHeroku上で見つからないこと、そしてglibcのバージョンが合わないことです。共有ライブラリの問題は-staticやheroku config:add LD_LIBRARY_PATH=./libsでlibsの中に共有ライブラリを詰めてデプロイしてしまう方法等で解決できる可能性がありますが、glibcのバージョン違いは如何ともし難いです。(* heroku config:addの方が簡単です)
なので、HerokuのCeladon cedar stackで使用されるディストロがUbuntu10.04LTSの間は、素直にUbuntu上に構築してdeployするのがいいと思います。
自分はMacOSX10.6.8にVirtualBoxを入れ、Ubuntu10.04LTS-64bitのイメージを落としてきた後64bit ubuntuとしてVirtualBoxでVMを立てました。64bitを使用しているのは、Herokuにデプロイするために必要だからです。

ghc-7.4.1を用意

Haskell-platformをソースからbuildするには、ここが参考になります。
まず、ghc-7.4.1をインストールしなければなりません。
GHCのインストール先をコントロールしたいので、

$ ./configure --prefix=chosen-directory
$ make install

とします。
chosen-directory/ghc-7.4.1/bin/にghcやらghciやらがあるとおもいます。./ghciを実行してみてください。
怒られるのではないでしょうか。libgmpがありませんよ、と。自分の環境ではlibgmp.so.3があったのでここを参考にシンボリックリンクを貼ってやりました。

$ cd /usr/lib
$ sudo ln -s libgmp.so.3 libgmp.so

ghciが動きましたでしょうか。とりあえずghcなどにパスを通してやりましょう。自分は~/.profileに

$ export PATH="chosen-directory/ghc-7.4.1/bin:$PATH"

って感じで加えました。

Haskell-platform-2012.2.0.0-64bitを用意

Haskell-platformのソースwgetします。インストール時に適当なdirectoryを指定します。

$ ./configure --prefix=chosen-directory-hplat

configure時に、ghcを指定しろと言われるでしょう。--with-ghc=chosen-directory/ghc-7.4.1/bin/ghcのように指定する必要があります。 --with-ghc-pkg, --with-ghc-hsc2hsについても同様です。
おそらくCライブラリが見つからんと怒られます。自分はzlibとOpenGLがないと怒られました。

$ sudo apt-get install zlib1g-dev
$ sudo apt-get install freeglut3-dev

configureが通ったら、

$ make
$ make install

です。成功しましたか?成功したらcabal等にパスを通したいので、chosen-directory-hplat/binをPATHに加えてください。

cabal-devインストール

はやってcabal install yesod-platformを実行しないでください。dependency hellに落ちてしまいます。
まずはcabal-devを用意します。cabal-devを導入することで、環境をsandbox化して用意し、明示的にどのパッケージを使用するのか指定することができます。現状でHackageに登録されているcabal-devはdependencyがおかしくなっているので、ソースから直接buildします。

$ git clone git://github.com/creswick/cabal-dev.git
$ cd cabal-dev
$ cabal update
$ cabal install

cabal-devがインストールされたら、PATHを通しましょう。cabal-dev --versionが実行できなければ、~/.cabal/binを通す必要があります。

Yesodのインストール

cabal-devが用意できたら、yesodを用途に分けて複数インストールするという手法を取ります。

  • yesod initを実行するためのグローバルなyesod
  • 各yesodプロジェクト内で実際にrunさせるためのローカルなyesod

yesod initのためのyesodは、適当なところにインストールしてやります。

$ cabal-dev install yesod-platform

そのディレクトリ内のcabal-dev/bin/にyesodが入っているのがわかると思います。
このディレクトリのcabal-dev/binにパスを通しておきます。
これでyesod initで実行されるのはこのグローバルな物が使われることになります。

Yesodプロジェクトの用意

早速プロジェクトを作りましょう。

$ yesod init

プロジェクトの名前とDBの種類等を指定すれば、プロジェクトの名前でフォルダが作られます。
ここではadamというプロジェクトをsqliteで作りました。
ここから、ローカルなyesodをインストールしてやります。

$ cd adam
$ cabal-dev install --only-dependencies

adam/cabal-dev/binにyesodが入っているでしょうか。
このローカルなyesodを使って開発を行っていきます。
adam直下で、

$ cabal-dev install                                #adam.cabalからadam本体をbuild
$ cabal-dev/bin/yesod --dev devel         #developer環境のyesodをrun

で、localhost:3000にアクセスすれば、Hello Yesodの完了です。

heroku-toolbeltのインストール

どうもrubygems経由でinstallしたheroku cliがuninitialized constant Heroku::API (NameError)というエラーでこけるので、heroku-toolbeltをinstallしました。apt-getではpackageが見つからなかったので、ここからinstall.shを取ってきて実行しました。
heroku loginでEmailを聞いてくれば成功です。
ここらでherokuのユーザー登録を済ませましょう。

Yesodアプリのdeploy準備

まずProcfileを移動し、Node.jsと見せかけるためのpackage.jsonを作ります。

$ cd adam
$ mv deploy/Procfile Procfile
$ echo'{ "name": "adam", "version": "0.0.1", "dependencies": {} }'>> package.json

.gitignoreを作成し、cabal-dev, dist, .static-cache, static/tmp, *.sqlite3等を含めてください。そして、git init, git add ., git commit -m 'initial commit'まで済ませてください。
いよいよプロジェクトをHerokuに登録します。

$ ssh-keygen -t rsa
$ heroku keys:add   //以上をしないと、public keyの認証によりあとでgit pushしたときに弾かれます
$ heroku login

adam直下で、

$ heroku create --stack cedar [name]

nameは指定しない場合は勝手に付けてくれるようです。
付けてくれた名前を、config/settings.xmlのapprootに設定します。
自分はdefaultとproductionの二つを書き換えておきました。
デプロイ用にビルドを行います。

$ cabal-dev configure -fproduction
$ cabal-dev build

デプロイ用のブランチを切ります。

$ git checkout -b deploy
$ git add dist/build/adam/adam -f
$ git commit -m 'deploy'

続けて、デプロイです。

$ git push heroku deploy:master
動作確認

さて、祈りながら以下のコマンドを実行しましょう。

$ heroku open

...どうですか?ブラウザが立ち上がりHelloの文字が見えましたか?
見えない場合は...

まとめ

このメモが皆さんの役に立ちますように。
これでデプロイ出来れば、scottyなどでも普通に行けそうですね。
最後に、参考にさせていただいた先人の皆さんに感謝です!!

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!