Contenu connexe
Similaire à Yesod on Heroku (20)
Yesod on Heroku
- 2. What is Heroku?
• PaaS (Platform as a Service) 型
• 当初は Ruby on Rails のみ
• Cedar Stack の導入で Python, Java, Scala,
Clojure, Node.js などに対応
• 1dyno (≒ プロセス), メモリ 300MB,
PostgreSQL 5MB まで 無料 で使える
• たくさんのアドオン
2 / 19
- 3. Dyno
http://www.heroku.com/how
• プロセスのようなもの
• サーバーや VM を意識する必要なし
• web, worker, clock などの Process Type
• Procfile をもとに生成される
yesod init した場合は deploy/Procfile に自動的に生成
• Process Type 毎に拡張可能
$ heroku ps:scale web=10 worker=2
$ heroku ps:scale web-1 worker+2
• 不安定になった Dyno は自動的に再起動される
3 / 19
- 4. Slug
• Slug = Dyno の元になるオブジェクト
• git push した際の hook で生成される
• 言語・フレームワーク独自のファイルの有無に
よって環境を識別する
• 判定に失敗した場合はデプロイを拒否さ
れる……
• package.json を置いておくと Node.js として
判定
4 / 19
- 6. Haskell on Heroku
Celadon Cedar Stack なら
Haskell アプリケーションをデプロイ可能!!!
Celadon Cedar Stack
• Ubuntu 10.04 LTS (lucid) (64bit)
• package.json ファイルを置いておくと Node.js
アプリケーションとして認識される
12.04 LTS が出た後はどうなるの……?
6 / 19
- 7. Heroku gem
• Heroku gem をインストール
$ gem install heroku
--user-install --no-ri --no-rdoc
• 公開鍵を登録
$ heroku login
Enter your Heroku credentials.
Email: user@example.com
Password:
7 / 19
- 8. Heroku で Haskell を動かす
• Node.js アプリに擬態
$ cat package.json
{ "name": "yesod-test",
"version": "0.0.1",
"dependencies": {} }
• Procfile を作成
$ cat Procfile
web: ./dist/build/yesod-on-heroku/yesod-on-heroku production -p $PORT
8 / 19
- 9. データベースを使う
• 環境変数 DATABASE_URL,
SHARED_DATABASE_URL を読んで自力で頑張る
• heroku package を使う
http://hackage.haskell.org/package/heroku
deploy/Procfile に詳しいやりかたが
書いてあるので……
9 / 19
- 10. デプロイ
• Cedar Stack にアプリを作成
$ heroku create --stack cedar
Creating strong-mist-1328... done, stack is cedar
http://strong-mist-1328.herokuapp.com/ | git@heroku.com:strong-mist-1328.gi
Git remote heroku added
• コンパイル
$ cabal configure -fproduction
$ cabal build
• デプロイ
$ git checkout -b deploy
$ git add dist/build/yesod-test/yesod-test
$ git commit -m "deploy"
$ git push heroku deploy:master
• $ heroku open
10 / 19
- 11. コンパイルする際注意すること
• Ubuntu 10.04 LTS (lucid) 64bit で動作するバイ
ナリを作成
• VM に lucid を入れてコンパイルするのが楽?
(lucid の GHC のバージョンは 6.12.1 …… orz)
• GHC はデフォルトでは……
• 可能な限り Haskell パッケージの共有ライブラリ を
利用せず静的にリンク
• 実行ファイル自体は動的リンク
• libyaml などのライブラリは動的リンク
→ 共有ライブラリが発見できない
11 / 19
- 12. エラーが起きたときは
• ログを確認してみる
$ heroku logs
2011-11-15T17:38:20+00:00 app[web.1]: ./dist/build/yesod-test/yesod-test:
error while loading shared libraries: libyaml-0.so.2:
cannot open shared object file: No such file or directory
2011-11-15T17:38:20+00:00 heroku[web.1]: Process exited
• リモートのシェル環境で調査
$ heroku run ldd dist/build/yesod-test/yesod-test
Running ldd ./dist/build/yesod-test/yesod-test attached to terminal... up, run.37
linux-vdso.so.1 => (0x00007fffb7dff000)
libz.so.1 => /lib/libz.so.1 (0x00007fe9963ba000)
libyaml-0.so.2 => not found
librt.so.1 => /lib/librt.so.1 (0x00007fe9961b1000)
libutil.so.1 => /lib/libutil.so.1 (0x00007fe995fae000)
libdl.so.2 => /lib/libdl.so.2 (0x00007fe995daa000)
libgmp.so.10 => not found
libffi.so.5 => not found
libm.so.6 => /lib/libm.so.6 (0x00007fe995b26000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007fe995908000)
libc.so.6 => /lib/libc.so.6 (0x00007fe995585000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe9965d9000)
12 / 19
- 14. 解決策: 静的リンク
全てのライブラリを静的にリンク
• yesod-test.cabal の ghc-options を書き換え
ghc に対して -optl-pthread -optl-static
フラグを指定
... (略)
executable yesod-test
if flag(devel)
Buildable: False
if flag(production)
cpp-options: -DPRODUCTION
ghc-options: -Wall -threaded -O2 -optl-pthread -optl-static
else
ghc-options: -Wall -threaded -O0
... (略)
14 / 19
- 15. 解決策: 静的リンク
問題がある物のみを静的にリンク
• package.conf.d/integer-gmp-*.conf を書き換え
• extra-libraries から yaml を消去
• ld-options: ”-Wl,-Bstatic” -lyaml ”-Wl,-Bdynamic”
と書き換えてしまう
これを
$ cat /var/lib/ghc/package.conf.d/yaml-0.5.2.conf
name: yaml
version: 0.5.2
id: yaml-0.5.2-90d2ec65096da81d098bd329cb16d6bf
... (略)
extra-libraries: yaml
extra-ghci-libraries:
include-dirs:
includes:
depends: aeson-0.6.0.1-1adff47713ff03277e972cd2e23ec8fc
... (略)
hugs-options:
cc-options:
ld-options:
framework-dirs:
frameworks:
haddock-interfaces: /usr/lib/ghc-doc/haddock/yaml-0.5.2/yaml.haddock
haddock-html: /usr/share/doc/libghc-yaml-doc/html/
15 / 19
- 16. 解決策: 静的リンク
問題がある物のみを静的にリンク
• package.conf.d/integer-gmp-*.conf を書き換え
• extra-libraries から yaml を消去
• ld-options: ”-Wl,-Bstatic” -lyaml ”-Wl,-Bdynamic”
と書き換えてしまう
こうする
$ cat /var/lib/ghc/package.conf.d/yaml-0.5.2.conf
name: yaml
version: 0.5.2
id: yaml-0.5.2-90d2ec65096da81d098bd329cb16d6bf
... (略)
extra-libraries:
extra-ghci-libraries:
include-dirs:
includes:
depends: aeson-0.6.0.1-1adff47713ff03277e972cd2e23ec8fc
... (略)
hugs-options:
cc-options:
ld-options: "-Wl,-Bstatic" -lyaml "-Wl,-Bdynamic"
framework-dirs:
frameworks:
haddock-interfaces: /usr/lib/ghc-doc/haddock/yaml-0.5.2/yaml.haddock
haddock-html: /usr/share/doc/libghc-yaml-doc/html/
16 / 19
- 17. 解決策: 共有ライブラリを含めてデプロイする
• 環境変数 LD_LIBRARY_PATH を指定する
• コンパイル時に -optl-Wl,-rpath,’$ORIGIN’
等として RPATH を埋め込む
今回は LD_LIBRARY_PATH を使う方法について解説
17 / 19
- 18. 解決策: 共有ライブラリを含めてデプロイする
• Heroku 環境に含まれていないライブラリをコ
ピーし git の管理下に
libyaml, libffi, libgmp などなど
• シェルスクリプト run を作成
$ cat run
#!/bin/sh
LD_LIBRARY_PATH=$PWD/dist/build/yesod-test
./dist/build/yesod-test/yesod-test -p $PORT -e production
• Procfile を書き換え
$ cat Procfile
web: ./run
18 / 19
- 19. まとめ?
• Ruby (heroku gem)
• Ubuntu 10.04 LTS (64bit)
用にビルド
• package.json を置いて
Node.js アプリを擬態
• 必要な知識 : Binary Hacks
19 / 19