OCamlで作ったWebアプリをHerokuで動かす方法(1) 〜OCamlnet編〜
PaaSであるHerokuには、Bulidpackという任意のコマンドをデプロイ時に実行できる仕組みがあります。 これを使って、OCamlで作ったWebアプリケーションをHeroku上で動作させる方法について紹介します。
てっとりばやく動かしたい人は、 heroku-buildpack-ocaml/sample-ocamlnet を見てもらうのが早いと思います。
前提
- Herokuのアカウントをもっている
- OCamlを動かす環境が揃っている
- Heroku toolbeltがインストールされている
Hello,worldを動かしてみる
まずは、標準ライブラリだけを使って、Webサーバを作ってみます。
とりあえずディレクトリの準備
適当なディレクトリを作ります。
$ mkdir hello
$ cd hello
buildpackを指定して、herokuにレポジトリを作成します。
$ heroku create buildpack-ocaml-hello
$ heroku config:set BUILDPACK_URL=https://github.com/heroku-buildpack-ocaml/heroku-buildpack-ocaml
Webサーバの作成
デプロイ時には ./configure
と make
が実行されるので、 make
で実行ファイルが生成されるようにします。
ここではOASISを使ってみます。
_oasis
に以下の内容を書きます。
OASISFormat: 0.3
Name: buildpack-ocaml-hello
Version: 1.0.0
Synopsis: sample for buildpack-ocaml
Authors: your name
License: GPL-3.0
Plugins: META (0.3), StdFiles (0.3), DevFiles (0.3)
Executable server
Path: src
BuildTools: ocamlbuild
MainIs: main.ml
BuildDepends: unix
src/main.ml
に以下の内容を書きます。
(* UNIXモジュールを使ってWebサーバを作る。
ポート番号はコマンドライン引数経由で受けとる。 *)
open Unix
let f _ out =
output_string out "HTTP/1.0 200 OK\n\nhello,world"
let _ =
let port =
int_of_string Sys.argv.(1)
in
establish_server f (ADDR_INET (inet_addr_of_string "0.0.0.0", port))
ためしに、ビルドしてみます。
$ oasis setup
$ make
$ ./main.native 8080
http://localhost:8080 にアクセスして、"hello,world!" が表示されることを確認しておきます。
そして、ここまでをコミットしておきます。
$ make clean
$ rm -rf setup.data
$ git add .
$ git commit -m "hello,world"
Herokuへのデプロイ
Procfile
に、サーバの起動方法を設定します。
web: ./main.native $PORT
あとは Procfile
をコミットし、Herokuにpushすればデプロイされます。 初回はちょっと時間がかかるので、コーヒーでも飲みながら待ちましょう。
$ git add Procfile
$ git commit -m "add heroku config"
$ git push heroku master
デプロイが終わったら、起動するプロセスの数を指定します。 無料枠だと1より大きくはできないので、1で我慢しておきましょう。
$ heroku ps:scale web=1
あとは、 http://buildpack-ocaml-hello.heroku.com/ にアクセスすれば、hello, world! と表示されます。
全ソースコード
https://github.com/heroku-buildpack-ocaml/sample-hello
ライブラリを追加したい
標準ライブラリだけでやるのは辛いので、opamを使ってライブラリをインストールしてます。
ocamlnetの追加
ここではネットワークプログラム用のライブラリ ocamlnet を使います。
まずは、opam経由でローカルにインストールします。
$ opam install ocamlnet
_oasis
を変更して、ocamlnetを使うようにします。
OASISFormat: 0.3
Name: buildpack-ocaml-hello
Version: 1.0.0
Synopsis: sample for buildpack-ocaml
Authors: your name
License: GPL-3.0
Plugins: META (0.3), StdFiles (0.3), DevFiles (0.3)
Executable server
Path: src
BuildTools: ocamlbuild
MainIs: main.ml
# ここをunixからocamlnetに変える
BuildDepends: ocamlnet
あとは src/main.ml
を書き換えるだけですが、長くなるので https://github.com/heroku-buildpack-ocaml/sample-ocamlnet/blob/master/src/main.ml からダウンロードしてきてください。 内容はocamlnetのexapmleをちょっと変えただけです。
ビルドして動作を確かめます。
$ make
$ ./main.native 8080
http://localhost:8080 にアクセスして、リンクとボタンが表示されているのを見てみましょう。
Herokuへのデプロイ
Heroku上でocamlnetをインストールするために、以下のような setup-opam
を用意しします。 これが ./configure
の前に実行されて、必要なパッケージがインストールできます。
#!/usr/bin/env bash
opam install -y ocamlnet
chmod +x setup-opam
して上で、コミット、pushします。
$ chmod a+x setup-opam
$ git add setup-opam
$ git commit -m "( ゚∀゚)o彡゚ opam! opam!"
$ git push heroku master
注意点
- heroku上にないライブラリに依存しているパッケージはインストールできません。(例: sqlite)。
- デプロイは15分以内に完了する必要があるので、あんまりビルドに時間がかかるパッケージはインストールできません。
ソースコード
https://github.com/heroku-buildpack-ocaml/sample-ocamlnet/
その他の情報
- buildpackを作ったときに使ったスクリプトは heroku-buildpack-ocaml/build-scripts/tree/master/ocamlbrew にあります。 別のバージョンのコンパイラを使いたい人は、これをいじるといいと思います。
- 何か不具合がありましたら heroku-buildpack-ocaml/heroku-buildpack-ocaml までご報告ください。 あなたの pull requestをお待ちしております。