SlideShare a Scribd company logo
1 of 20
Download to read offline
Yesod on Heroku

@thimura hontai

   2012-04-22




                  1 / 19
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
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
Slug


• Slug = Dyno の元になるオブジェクト
• git push した際の hook で生成される
• 言語・フレームワーク独自のファイルの有無に
  よって環境を識別する
• 判定に失敗した場合はデプロイを拒否さ
  れる……
• package.json を置いておくと Node.js として
  判定



                                     4 / 19
Haskell は?




             5 / 19
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
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
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
データベースを使う


• 環境変数 DATABASE_URL,
  SHARED_DATABASE_URL を読んで自力で頑張る
• heroku package を使う
  http://hackage.haskell.org/package/heroku

    deploy/Procfile に詳しいやりかたが
           書いてあるので……




                                         9 / 19
デプロイ

• 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
コンパイルする際注意すること

• Ubuntu 10.04 LTS (lucid) 64bit で動作するバイ
  ナリを作成
• VM に lucid を入れてコンパイルするのが楽?
  (lucid の GHC のバージョンは 6.12.1 …… orz)
• GHC はデフォルトでは……
   • 可能な限り Haskell パッケージの共有ライブラリ を
     利用せず静的にリンク
   • 実行ファイル自体は動的リンク
   • libyaml などのライブラリは動的リンク

→ 共有ライブラリが発見できない


                                           11 / 19
エラーが起きたときは

• ログを確認してみる
 $ 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
解決策




• 静的リンクする
• 共有ライブラリを含めてデプロイする




                      13 / 19
解決策: 静的リンク
                    全てのライブラリを静的にリンク




• 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
解決策: 静的リンク
                     問題がある物のみを静的にリンク

• 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
解決策: 静的リンク
                     問題がある物のみを静的にリンク

• 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
解決策: 共有ライブラリを含めてデプロイする




 • 環境変数 LD_LIBRARY_PATH を指定する
 • コンパイル時に -optl-Wl,-rpath,’$ORIGIN’
  等として RPATH を埋め込む
今回は LD_LIBRARY_PATH を使う方法について解説




                                       17 / 19
解決策: 共有ライブラリを含めてデプロイする


 • 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
まとめ?



 • Ruby (heroku gem)
 • Ubuntu 10.04 LTS (64bit)
   用にビルド
 • package.json を置いて
   Node.js アプリを擬態
 • 必要な知識 : Binary Hacks




                              19 / 19
ご静聴ありがとうございました




                 20 / 19

More Related Content

What's hot

Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on dockerHiroshi Miura
 
Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on dockerHiroshi Miura
 
VarnishではじめるESI
VarnishではじめるESIVarnishではじめるESI
VarnishではじめるESIIwana Chan
 
Docker handson
Docker handsonDocker handson
Docker handsonkoda3
 
Nuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlifyNuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlifyogawatti
 
2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム
2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム
2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウムComputational Materials Science Initiative
 
第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西Masahide Yamamoto
 
ラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよnpsg
 
コンテナ型仮想化とはなんだったのか
コンテナ型仮想化とはなんだったのかコンテナ型仮想化とはなんだったのか
コンテナ型仮想化とはなんだったのかえむ ばーど
 
Raspberrypi+yocto in Yocto Workshop Japan #1
Raspberrypi+yocto in Yocto Workshop Japan #1Raspberrypi+yocto in Yocto Workshop Japan #1
Raspberrypi+yocto in Yocto Workshop Japan #1kazuya-nisimura
 
Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Manabu Ori
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lispirix_jp
 
Programming Hive Reading #3
Programming Hive Reading #3Programming Hive Reading #3
Programming Hive Reading #3moai kids
 
Linux kernelのbspとupstream
Linux kernelのbspとupstreamLinux kernelのbspとupstream
Linux kernelのbspとupstreamwata2ki
 
OSC Tokyo fall LT~Dockerで分散処理をやってみた
OSC Tokyo fall LT~Dockerで分散処理をやってみたOSC Tokyo fall LT~Dockerで分散処理をやってみた
OSC Tokyo fall LT~Dockerで分散処理をやってみたatk1234
 
第1回 一撃サーバー構築シェルスクリプト勉強会
第1回 一撃サーバー構築シェルスクリプト勉強会第1回 一撃サーバー構築シェルスクリプト勉強会
第1回 一撃サーバー構築シェルスクリプト勉強会Yasutaka Hamada
 
"Programming Hive" Reading #1
"Programming Hive" Reading #1"Programming Hive" Reading #1
"Programming Hive" Reading #1moai kids
 
VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門Masashi Shinbara
 

What's hot (20)

Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on docker
 
Building production server on docker
Building production server on dockerBuilding production server on docker
Building production server on docker
 
VarnishではじめるESI
VarnishではじめるESIVarnishではじめるESI
VarnishではじめるESI
 
Docker handson
Docker handsonDocker handson
Docker handson
 
Nuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlifyNuxt.js + microCMS + netlify
Nuxt.js + microCMS + netlify
 
2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム
2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム
2015-09-02 @ 大型実験施設とスーパーコンピュータとの連携利用シンポジウム
 
第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西第一回コンテナ情報交換会@関西
第一回コンテナ情報交換会@関西
 
ラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよラズパイ2で動く Docker PaaSを作ってみたよ
ラズパイ2で動く Docker PaaSを作ってみたよ
 
Docker Swarm入門
Docker Swarm入門Docker Swarm入門
Docker Swarm入門
 
コンテナ型仮想化とはなんだったのか
コンテナ型仮想化とはなんだったのかコンテナ型仮想化とはなんだったのか
コンテナ型仮想化とはなんだったのか
 
Capistrano
CapistranoCapistrano
Capistrano
 
Raspberrypi+yocto in Yocto Workshop Japan #1
Raspberrypi+yocto in Yocto Workshop Japan #1Raspberrypi+yocto in Yocto Workshop Japan #1
Raspberrypi+yocto in Yocto Workshop Japan #1
 
Pgcon2012 ori-20120224
Pgcon2012 ori-20120224Pgcon2012 ori-20120224
Pgcon2012 ori-20120224
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lisp
 
Programming Hive Reading #3
Programming Hive Reading #3Programming Hive Reading #3
Programming Hive Reading #3
 
Linux kernelのbspとupstream
Linux kernelのbspとupstreamLinux kernelのbspとupstream
Linux kernelのbspとupstream
 
OSC Tokyo fall LT~Dockerで分散処理をやってみた
OSC Tokyo fall LT~Dockerで分散処理をやってみたOSC Tokyo fall LT~Dockerで分散処理をやってみた
OSC Tokyo fall LT~Dockerで分散処理をやってみた
 
第1回 一撃サーバー構築シェルスクリプト勉強会
第1回 一撃サーバー構築シェルスクリプト勉強会第1回 一撃サーバー構築シェルスクリプト勉強会
第1回 一撃サーバー構築シェルスクリプト勉強会
 
"Programming Hive" Reading #1
"Programming Hive" Reading #1"Programming Hive" Reading #1
"Programming Hive" Reading #1
 
VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門
 

Similar to Yesod on Heroku

LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!KLab株式会社
 
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2tamtam180
 
Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)tamtam180
 
Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...
Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...
Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...NTT DATA Technology & Innovation
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Mori Shingo
 
Docker on RHEL & Project Atomic 入門 - #Dockerjp 4
Docker on RHEL & Project Atomic 入門 - #Dockerjp 4Docker on RHEL & Project Atomic 入門 - #Dockerjp 4
Docker on RHEL & Project Atomic 入門 - #Dockerjp 4Emma Haruka Iwao
 
Introduce that Best practices for writing Dockerfiles
Introduce that Best practices for writing DockerfilesIntroduce that Best practices for writing Dockerfiles
Introduce that Best practices for writing DockerfilesYukiya Hayashi
 
Dockerハンズオン
DockerハンズオンDockerハンズオン
DockerハンズオンKazuyuki Mori
 
Yocto bspを作ってみた
Yocto bspを作ってみたYocto bspを作ってみた
Yocto bspを作ってみたwata2ki
 
Dockerイメージ構築 実践テクニック
Dockerイメージ構築 実践テクニックDockerイメージ構築 実践テクニック
Dockerイメージ構築 実践テクニックEmma Haruka Iwao
 
Nseg20120825
Nseg20120825Nseg20120825
Nseg20120825hiro345
 
node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成shigeki_ohtsu
 
Hive undocumented feature
Hive undocumented featureHive undocumented feature
Hive undocumented featuretamtam180
 
PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション
PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC WebアプリケーションPlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション
PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC WebアプリケーションKazuhiro Hara
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門sandai
 
Niktoとかburpsuite触ってみよう
Niktoとかburpsuite触ってみようNiktoとかburpsuite触ってみよう
Niktoとかburpsuite触ってみようionis111
 

Similar to Yesod on Heroku (20)

LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!
 
Vyatta 改造入門
Vyatta 改造入門Vyatta 改造入門
Vyatta 改造入門
 
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
 
Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)
 
Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...
Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...
Apache BigtopによるHadoopエコシステムのパッケージング(Open Source Conference 2021 Online/Osaka...
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋
 
Docker on RHEL & Project Atomic 入門 - #Dockerjp 4
Docker on RHEL & Project Atomic 入門 - #Dockerjp 4Docker on RHEL & Project Atomic 入門 - #Dockerjp 4
Docker on RHEL & Project Atomic 入門 - #Dockerjp 4
 
Introduce that Best practices for writing Dockerfiles
Introduce that Best practices for writing DockerfilesIntroduce that Best practices for writing Dockerfiles
Introduce that Best practices for writing Dockerfiles
 
Dockerハンズオン
DockerハンズオンDockerハンズオン
Dockerハンズオン
 
Yocto bspを作ってみた
Yocto bspを作ってみたYocto bspを作ってみた
Yocto bspを作ってみた
 
Dockerイメージ構築 実践テクニック
Dockerイメージ構築 実践テクニックDockerイメージ構築 実践テクニック
Dockerイメージ構築 実践テクニック
 
Nseg20120825
Nseg20120825Nseg20120825
Nseg20120825
 
Sinatra and heroku for mac
Sinatra and heroku for macSinatra and heroku for mac
Sinatra and heroku for mac
 
Pdp11 on-fpga
Pdp11 on-fpgaPdp11 on-fpga
Pdp11 on-fpga
 
node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成
 
Git (実践入門編)
Git (実践入門編)Git (実践入門編)
Git (実践入門編)
 
Hive undocumented feature
Hive undocumented featureHive undocumented feature
Hive undocumented feature
 
PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション
PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC WebアプリケーションPlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション
PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門
 
Niktoとかburpsuite触ってみよう
Niktoとかburpsuite触ってみようNiktoとかburpsuite触ってみよう
Niktoとかburpsuite触ってみよう
 

Yesod on Heroku

  • 1. Yesod on Heroku @thimura hontai 2012-04-22 1 / 19
  • 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
  • 5. Haskell は? 5 / 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