目次

Haskellプログラムのデプロイメント

こりん・2018-02-28初出版・2020-06-16更新

「一体どうHaskellのプログラムをデプロイするのか」

既にコンテナ・システムがあって混ぜたいHaskellはただ一部だけの場合は「Docker」を 使っても問題ありません。

他には「Heroku」が凡Haskeller(自分を含めて)にとって一番使いやすいと思います。

楽の道: Heroku

ただ小規模のサーバーをどこか載せたい。

「Heroku」はこれにぴったりです。 git push だけで自動デプロイメントができ、再デ プロイが速くなる様に stack でダウンロードされるdependenciesが全部キャッシュ されます。

Herokuのサーバーは「dyno」といって、一番安いのは無料です。30分経ってサーバーにリ クエストがなければ眠ってしまいますが、また呼んだら数秒で再起動します。有料の 「dyno」は眠ったりしません。

プロジェクト管理に heroku のCLIツールもありますが、この簡単な場合には特に必要 ありません。下にも「Namecheap」との接続方法の説明も含めています。

$PORT からリクエスト

Herokuに載せるサーバーは普段の80・8080・443等ではなく、 $PORT からリクエストを 取ります。まだ開発の最中ではこれは少し厄介な部分がありますが、下のコードを使えば 問題ありません:

  {-# LANGUAGE DeriveAnyClass #-}
  {-# LANGUAGE DeriveGeneric  #-}

  import qualified Network.Wai.Handler.Warp as W
  import           Options.Generic
  import           System.Environment (lookupEnv)
  import           Text.Read (readMaybe)

  data Args =
    Args { port :: Maybe Int <?> "Port to listen for requests on." }
    deriving (Generic, ParseRecord)

  app :: Application  -- Some `wai` Application

  main :: IO ()
  main = do
    Args (Helpful p) <- getRecord "Backend server for foobar.com"
    herokuPort <- (>>= readMaybe) <$> lookupEnv "PORT"
    let prt = maybe 8080 id $ p <|> herokuPort
    putStrLn $ "Listening on port " <> show prt
    W.run prt app

開発中、サーバーの機動はこうなります:

  stack exec -- server --port 8080

Herokuの設定

Repoでの Procfile

コミットしなければならないのは Procfile というファイルだけです。Herokuが プロジェクトを構築した後 Procfile にあるコマンドを実行します。例:

web: server

server とは .cabal に決めたexecutableの名前です。プログラム引数もあったら この様に:

web: server --js app.min.js

Heroku.comで

他の設定は全部直接Herokuのサイトでできます。勿論登録が必要です。

「Dashboard」に入るとまずは新しい「Heroku・アプリ」を作りましょう(右上で「New」 から「Create New App」)。できたら「Deploy」のタブが見えてくるはずです:

ページの後半に見える「CLI」指示を無視してデプロイ方法を「Github」と選んで 繋げたいrepoを入力しましょう。

次は「Settings」のタブでの「Buildpacks」の所:

「Buildpack」とはHeroku用語です。言語そろぞれにあり、構築に必要な複数のスクリプ トの意味を表します。 stack を使う「buildpack」を入れましょう。「Add buildpack」 をクリックしてこれを:

https://github.com/mfine/heroku-buildpack-stack

stack を使うプロジェクトはこれで構築してdependenciesがキャッシュされます。 HaskellをHerokuで使えるように頑張ったMark FineさんとJoe Nelsonさん達に感謝しましょう。

デプロイメント

git push origin master だけでプロジェクトがデプロイされます!

Namecheapとの接続

具体的な指示は こちら

HTTPS

有料の「dyno」であればHerokuは Let's Encrypt を通して自動的にHTTPSの管理をしてく れます。すこしだけNamecheapの設定を変えればHTTPSは我が手に。

Namecheapでは各ホストの Value

yourappname.herokuapp.com

からこれに変えます:

yourdomain.com.herokudns.com

本サイトの場合、 fosskers.herokuapp.comfosskers.ca.herokudns.com になり ました。ネットの隅まで設定変換が広がるのは少し時間かかりますが、できたらそのまま https://yourdomain.com が使えるはずです。

コンテナの道: stack とDocker

個人的に言うと、HaskellだけのシステムならDockerは必要ありません。開発者としてこ ういう判断はよく上がするものなので、仕方なくコンテナを使わざるを得ないのであれば stack がまた助けてくれます。

stack.yaml にこの様な設定を入力すれば:

  image:
    containers:
      - base: "fpco/ubuntu-with-libgmp:14.04"
        name: "foobar-server"
        entrypoints:
          - foobar-server-exe

そしてこのコマンドを実行すると:

  stack image container

Dockerのイメージが構築されます。できたらいつものコンテナ・デプロイメント・システ ムに混ぜる事ができます。より細かい指示は stack公式サイト へ(英語)。

ポスト一覧