私の環境では、Keter をダウンロードすることができませんでした。
色々な環境で Keter のダウンロードとインストールを試みましたが、すべて失敗 しました。Keterのサイトの冒頭に記載されている「一時的にKeterを有効にする」方法 も試しましたが、上手く動作しませんでした。
そこで、現時点で Warp & Wai アプリのデプロイに成功している Dokku を使って Yesod アプリをデプロイすることを試したところ無事に成功しました。
当初は、Dokku で Yesod アプリをデプロイすることは成功したり失敗したりと色々 でした。2019年02月14日に、このページを掲載した時点では、アプリを Stack と Cabal で2回ビルドしていましたが、それも成功の確率を増やすために模索した方法の 一つでした。しかし後日、デプロイに失敗する原因がわかりましたので、Stack で1回だけビルドする方法に変更することにします。
Yesod アプリを Dokku でデプロイすることに失敗する理由は単にリモートサーバー のメモリ不足だとわかりました。リモートサーバーメモリを2GBに増やすと、 1回では成功しないかもしれませんが、数回デプロイを繰り返すと成功します。 8GBとかに増やすと、おそらく1回でデプロイに成功するでしょう。
デプロイに失敗した場合は、再度デプロイを試みる前に、[stack clean」と「stack build」でアプリをビルドし直して、「git add .」と「git commit -m "xxx"」 をやり直してください。
Ubuntu は「 Conoha 」を参考に用意してください。
CentOS は「 CentOS で Dokkuを参考に用意してください。
Dokku の必要条件は 1GB以上のメモリですが、Yesodをデプロイするには、2GB 以上 のサーバーをお勧めします。
私の場合ですと、今回のサンプルは、2GBのUbuntuサーバーに対して2回目のデプロイ で成功。4GBのUbuntuサーバーに対しては1回目のデプロイで成功しています。
Ubuntu の場合も、CentOS の場合も同じです。
$ su dokku
$ cd
$ dokku apps:create yesod-web
ここからは、ローカルコンピューターでの作業です。
よりシンプルにするために、プロジェクトを手動で作成します。
$ mkdir yesod-web
$ cd yesod-web
$ mkdir src
「yesod-web」プロジェクト内に、次の内容の「yesod-web.cabal」というファイルを 作ります。
name: yesod-web
version: 0.1.0.0
category: Web
build-type: Simple
cabal-version: >=1.10
executable yesod-web
main-is: Main.hs
build-depends: base >=4.10 && <4.11
, yesod
hs-source-dirs: src
default-language: Haskell2010
「yesod-web」プロジェクト内の「src
」ディレクトリ内に、
次の内容の「Main.hs
」というファイルを作ります。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
import Yesod
import System.Environment
import Control.Monad
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
instance Yesod HelloWorld
getHomeR :: Handler Html
getHomeR = defaultLayout [whamlet|
<h1>Hello Yesod!</h1>
<h3>This is a Yesod remote site.</h3>
|]
main :: IO ()
main = do
port <- liftM read $ getEnv "PORT"
warp port HelloWorld
ビルド
$ stack init
$ stack build
初回のビルドは「Yesod」の開発環境と実行環境をインストールするため、 非常に時間がかかります。2回目からのビルドはすぐに終わります。 「stack init」は、初回の1回だけで構いません。
なお、「Yesod」のオフィシャルページでは、「Yesod コマンド」 をインストールしなければならないことになっていますが、 インストールしなくても問題なくビルドできます。 もしビルドできない場合は次のようにして、 「yesod コマンド」をインストールして、ビルドをし直してください。 「yesod コマンド」のインストールには、すごく時間がかかります。
$ stack install yesod-bin
Dokkuは、まだHaskellに対応していないため、Herokuの「buildpack」
を利用します。「yesod-web」プロジェクト内に次の内容で
「.buildpacks
」というファイルを作ってください。
.buildpacks
https://github.com/mfine/heroku-buildpack-stack
Herokuは「Procfile」というファイルが必要です。
「yesod-web」プロジェクト内に次の内容で
「Procrile
」というファイルを作ってください。
Procfile
web: yesod-web
「123.123.123.123」の部分は、サーバーのIPアドレスです。
$ git init
$ git add .
$ git commit -m "yesod-web"
$ git remote add dokku dokku@123.123.123.123:yesod-web
$ git push dokku master
初回のデプロイは、Haskellの実行環境もインストールしますので、 かなりの時間がかかります。
同じリポジトリに更新ファイルをデプロイする場合は、 2回目からはそれほど時間がかかりません
違うリポジトリにデプロイする場合は、また時間がかかります。
次のように表示されたらデプロイは成功しています。
=====> Application deployed:
https://123.123.123.123:12345
To 123.123.123.123:yesod-web
* [new branch] master -> master
表示されたアドレスはメモしておいてください。
CentOSサーバーにデプロイした場合はアドレスがハイフンで区切られています。 これをドット区切りに直してください。
https://123-123-123-123:12345
↓
https://123.123.123.123:12345
さらにCentOSサーバーでは、
ファイアーウォールに指定のポートのアクセスを許可させなければなりません。
CentOSサーバにログインして次の作業をしてください。「:
」の後の5桁もしくは4桁の数字が
ポート番号です。なお、この作業はUbuntuサーバーでは必要ありません。
$ firewall-cmd --zone=public --add-port=12345/tcp --permanent
$ firewall-cmd --reload
ブラウザで新規ウィンドウか新規タブを開いて、URLフィールドに表示されたアドレスを 入力して実行します。
CentOSサーバーの場合はドット区切りに直したアドレスを入力してください。
上記のように表示されたら成功です。
上記のように表示されたらプロジェクトのどこかにミスがあります。
デプロイを始めてからすぐにエラーが出る場合は、プロジェクトの設定のどこかに ミスがあります。Dokkuの設定やプロジェクトの設定をもう一度見直してください。
デプロイを始めてからしばらくして次のメッセージが出た場合は、リモートサーバー側の 問題です。
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'dokku@123.123.123.123:yesod-sample'
リモートサーバーのメモリを増やすか、再度デプロイを試みてください。デプロイを 繰り返すと上手くいく場合もあります。
再度デプロイをする場合は、念のために「stack clean」と「stack build」で プロジェクトをビルドしなおして、「git add .」と「git commit -m "yesod-web"」で git に登録しなおしてください。私の場合ですと、このサンプルは、2GBのUbuntuサーバーに対して2回目のデプロイ で成功し、4GBのUbuntuサーバーに対しては1回目のデプロイで成功しています。