Edited at

herokuにhaskellのウェブアプリをdocker:releaseをつかってデプロイしてみる

More than 3 years have passed since last update.

herokuにHaskellのウェブアプリをデプロイするのにbuildpack APIを調べようとしたらDockerをつかったリリースができることを知ったので、試した。

デプロイするアプリケーションはここでつくったものがあるのでこれを利用する。イメージの名前はeiel/wai-sampleです。


準備

dockerコマンドが使える状態になっている必要があります。

また、herokuコマンドをインストールして、dockerプラグインをインストールする必要があります。

$ heroku plugins:install heroku-docker


Procfileの作成

Procfileを作成します。/app/wai-sampleで実行できるようにしてありますので、

web: /app/wai-sample

とします。


app.json


app.jsonに image キーが必要になります。eiel/wai-sampleを利用します。


app.json

{

"image": "eiel/wai-sample"
}


heroku docker:init

ここまで進めるとheroku docker:initで必要なファイルを生成できます。

$ heroku docker:init

このコマンドを実行するとDockerfileとdocker-compose.ymlが生成されます。

FROM eiel/wai-sample


docker-compose.yml

web:

build: .
command: 'bash -c ''wai-sample'''
working_dir: /app/user
environment:
PORT: 8080
ports:
- '8080:8080'
shell:
build: .
command: bash
working_dir: /app/user
environment:
PORT: 8080
ports:
- '8080:8080'
volumes:
- '.:/app/user'


デプロイする

herokuにアプリケーション領域をつくってデプロイします。

$ git init

$ git add .
$ git commit -m "initial commit"
$ heroku create
$ heroku docker:release

これで終了です。

$ heroku open

で、ウェブアプリをブラウザでひらくことができます。


もっと詳しく

docker:releaseはDockerイメージ内の/appをherokuにアップロードしてくれます。その後cd /app/user && 「Procfile」の内容を実行してくれます。

これだけわかっていればHaskell以外のアプリケーションも動かせると思います。

docker release内部ではRelease APIを使用しているだけなので、dockerを使わずともLinux用のバイナリを生成してRelease APIをつかってデプロイすることもできると思います。


バイナリの生成

Docker内で生成しています。これを補助するために作成したDockerImageも用意しています。

Dockerfileはこっちにあります。

ビルド時間短縮するために warp のビルドまで済ませてあります。

このイメージをもとに wai-sample のイメージを生成しています。

/appにバイナリを配置して、/app/userディレクトリをつくっておくことでheroku docker:releaseでそのまま使えるようにしています。


CIでビルド

Docker内で生成してもよいですが、CIでビルドしてバイナリだけとりだして、Docker化してあげる方法があります。

イメージも小さくなるのでおすすめです。(いっそCIでheroku releaseしたいけど今回はやりませんでした)

CircleCIだとコンパイル結果のキャッシュをきかせたりできるので2回目以降のビルドはとても早いです。

circle.ymlの例


circle.yml

machine:

services:
- docker
dependencies:
cache_directories:
- "~/.stack"
pre:
- wget -q -O- https://s3.amazonaws.com/download.fpcomplete.com/ubuntu/fpco.key | sudo apt-key add -
- echo 'deb http://download.fpcomplete.com/ubuntu/precise stable main'|sudo tee /etc/apt/sources.list.d/fpco.list
- sudo apt-get update && sudo apt-get install stack -y
override:
- stack setup
- stack install
- stack build --test --only-dependencies

test:
override:
- stack test

deployment:
docker:
branch: master
commands:
- mkdir dist
- cp `stack path --local-bin-path`/wai-sample dist/
- docker build -t eiel/scotty-sample -f Dockerfiles/CircleCI .
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
- docker push eiel/wai-sample


FROM google/debian:wheezy

COPY dist/scotty-sample /app/
RUN mkdir /app/user

google/debian:wheezyを指定しているのは、私がGCEで使うことが多いので、指定しているだけです。お好みで。


参考文献