stackが出現してYesod開発が飛躍的に安定するようになり、Webアプリ作成が現実的な選択肢になりました。実際、私も仕事で1つ、Webアプリをリリースした経験があります(ごく小規模ではありますが)。
Webアプリは作っただけでは当然使うことができず、サーバにデプロイする必要があります。
今回はHaskell製のデプロイツールであるketerをご紹介します。
keterとは
keterはYesodの作者(の一人?)であるMichael Snoyman氏が開発している、デプロイを支援するツールです。Haskellで作られています。
恐らくYesodで作られたWebアプリをデプロイすることを念頭に置かれているとは思いますが、それに縛られるものではありません。
ソースはGitHubで公開されています。
keterの機能
本家のREADME.mdから抜粋すると・・・
- 80番ポートにバインドし、リバースプロキシとして動作する。所定のホスト名でのリクエストをWebアプリにブリッジする
- 必要があればSSLを提供する
- 自動的にWebアプリを起動し、監視し、プロセスが死んでいたら再度起動する
- グレイスフルな再デプロイのサポート。現在のプロセスは活かしたまま別のWebアプリプロセスを起動。正常に起動したらリバースプロキシの向き先を変えることで、Webアプリがダウンする時間帯を無くす
- ログファイルを管理
keterによるデプロイサイクル
- Webアプリをビルド、実行可能ファイルを作る
- keterファイルを作成
- keterファイルとは、
config/keter.ym.
、実行可能ファイル、静的リソースをtar形式にまとめてgzipしたファイルです。 - Yesodの場合、
yesod keter
というコマンドでketerファイルが作れます。stackを併用していることがほとんどだと思うので、実際に実行するコマンドは
stack exec -- yesod keter
となります。
- keterファイルとは、
- keterファイルをscpコマンドなどで
/opt/keter/incoming
に送る
以上の操作で、keterは再デプロイを実施してくれます。
Yesodとketer
stackのテンプレートを使ってYesodプロジェクトを作ると、config/keter.yml
というファイルが作られます。
keterを使ってデプロイしてね、と言われているようなものですね。
ただ、環境によってはstackが生成するketer.ymlの中に書かれている実行ファイルのパスが、実際にビルドして作られる実行ファイルのパスと異なることがあります。
この場合、「zipファイルの解凍に失敗したよー」みたいなエラーが報告されてしまいます。実行ファイルのパスがおかしいとは、まず分からないエラーですので、ご注意を・・・
keterの設定
keterの設定ファイルは、各Webアプリが持つ keter.yml
に加え、サーバ側が持つ keter-config.yaml
があります。
keter.ymlの設定内容
Yesodで作ったプロジェクトであれば config/
ディレクトリの中にあります。
下記が設定例です。
user-edited: true # trueにしておかないと編集が有効になりません
stanzas:
- type: webapp
exec: ../dist/bin/<実行ファイル> # keter.ymlから見た時の相対パスで記載しています
args: []
hosts: # keterでブリッジするホスト名を列挙します
- localhost
- example.com
requires-secure: true # HTTPSのみ許可する場合にtrueにします. HTTPへのリクエストはHTTPSにリダイレクトされます
plugins:
postgres: false # PostgreSQLを使っていてもfalseにしないと動きません. 理由はよく分からない・・・
keter-config.yamlの設定
デフォルトでは /opt/keter/etc/
ディレクトリの中にあります。
重要なのは、SSLを使う際のキーファイルの設定と、環境変数の設定です。
下記が設定例です。
# Directory containing incoming folder, where to store logs, etc. Relative to
# the config file directory.
root: ..
listeners:
# HTTP
- host: "*4" # Listen on all IPv4 hosts
port: 80 # Could be used to modify port
# HTTPS
- host: "*4"
port: 443
key: /etc/certs/private.key
certificate: /etc/certs/app.cer
chain-certificates:
- /etc/certs/middle-ca.cer
env:
PGHOST: host
PGUSER: user
PGPASS: pass
PGDATABASE: dbname
ログを確認する
ログファイルは /opt/keter/log/
ディレクトリの下に作られます。このディレクトリの下には、更に次の2種類のディレクトリが作られます。
- app-<アプリ名>:Webアプリが出力するログ
- keter:keter自体が出力するログ
最新のログは current.log
というファイルに出力され、それ以前のファイルは日付と時刻から成るファイル名が付けられます。
-rw-r--r-- 1 root root 1292 Jul 20 02:48 20160719_175032.log
-rw-r--r-- 1 root root 1954 Jul 20 02:59 20160719_181326.log
-rw-r--r-- 1 root root 1616 Jul 20 09:40 20160727_022327.log
-rw-r--r-- 1 root root 368 Jul 27 11:23 20160727_023041.log
-rw-r--r-- 1 root root 5642 Jul 27 14:03 20160727_051719.log
-rw-r--r-- 1 root root 261 Jul 27 14:17 20160727_051739.log
-rw-r--r-- 1 root root 764 Jul 27 14:28 20160727_053155.log
-rw-r--r-- 1 root root 2592 Jul 27 16:34 20160727_080003.log
-rw-r--r-- 1 root root 18918 Jul 28 20:05 20160729_013832.log
-rw-r--r-- 1 root root 432 Jul 29 10:38 20160729_015712.log
-rw-r--r-- 1 root root 432 Jul 29 10:57 20160729_024933.log
-rw-r--r-- 1 root root 60455 Nov 16 12:32 20161116_050953.log
-rw-r--r-- 1 root root 4406 Dec 22 07:29 current.log