みずぴー日記

人間の再起動ボタンはハワイのビーチにある

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サーバの作成

デプロイ時には ./configuremake が実行されるので、 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/

その他の情報