HaskellJP WikiをHerokuに上げるまで

by Yuji Yamamoto on December 20, 2014

Tagged as: Haskell, Heroku.

この記事は、 Haskell Advent Calendar 2014の12月20日の記事です。

業務連絡:HaskellJP WikiはHerokuにお引っ越ししました。

きっかけはHaskellJPのGoogle グループに、ある日突然現れた投稿でした。

すいません、、、http://wiki.haskell.jp/ をシャットダウンしようと思います

それまでHaskellJP Wikiの管理をされていたmasterqこと岡部さんが、 HaskellよりもATSという言語に惹かれるようになったのをきっかけに、 HaskellJP Wikiの管理をやめることになってしまったのです1

スタートHaskell 2の記録など、私にとっても思い出深いコンテンツが含まれるHaskellJP Wikiがこのままなくなってしまうことは、避けたい事態でした。
そこでどうにか復活させたいと申し出たところ、岡部さんが、HerokuでHaskell製のWebアプリを動かす方法が最近出来たのでどうか、と教えて下さいました。
Herokuならとりあえずは無料でできるしいいや、ということで軽いノリで始めたところ … 意外とあっさりできちゃったので、今回は方法を共有したいと思います。
HaskellJP WikiはgititというWikiシステム(もちろんHaskell製)で動いていますので、以下の方法はgititをHerokuで使う場合にほぼそのまま使える方法です。 みなさんもgititでWikiを作りたいということがあれば、ぜひお試しください。

1. GitHubのOAuth ApplicationとしてHaskellJP Wikiを登録する

新しくなったHaskellJP Wikiでは、GitHubのOAuthを利用してユーザーの登録・認証を行うようになっています。 そのため、作成したいWiki毎にGitHubのOAuth Applicationとして登録する必要があります。
最初にhttps://github.com/settings/applications/newに行って、作成したいWikiの情報を登録しましょう。
とりあえずバリデーションエラーにならないよう適当に埋めればよいのですが、「Authorization callback URL」という項目は重要です。 ここには「<Wikiに設定する予定のドメイン>/_githubCallback」という値を入力してください。 HaskellJP Wikiの場合はやはり「http://wiki.haskell.jp/_githubCallback」でした。

OAuth Applicationなんで当然ですが、作成したらあとでそのClient IDとClient Secretを利用するので、作成後の画面は開きっぱなしにでもしておきましょう。

2. Wikiデータ用のリポジトリを作って、deployキーを登録する

今度は、gititのWikiデータを保存するリポジトリを作りましょう2
gititはその名が表す通り、Wikiデータの変更をgitで管理するようになっています。
「それだとファイルシステムに直接データを保存することになるから、dynoがkillされるとファイルシステムも消えちゃうHerokuでは動かせないのでは?」と疑問に思う方もいらっしゃるかもしれません。
今回利用するmietekさんがforkしたgititは、 dynoを起動するたびに元のリポジトリからgit pullし、Wikiが更新されるたびに元のリポジトリにgit pushする、 というなかなかアクロバティックなアプローチでこの問題を回避しています。
ここで作るのは、その際に使用する「元のリポジトリ」と、それとgit pullしたりgit pushしてWikiデータをやり取りする際の公開鍵と秘密鍵のペアです。
gititのデータが入ったgitリポジトリであれば何でも良いはずですが、ここではGitHubを利用した方法を説明します。

  1. お好きな名前で新しくGitHubにリポジトリを作りましょう(作り方は割愛します)。もちろんすでにWikiデータが入ったリポジトリがあるならそれでもOKです。
  2. 公開鍵を作ったリポジトリに登録するので、当然ながらssh-keygenを使って新たに作成しましょう。gititが機械的に利用するものなので、passphraseは空にしてください3

    $ ssh-keygen -f deploy_key
  3. 作成した公開鍵ファイルと秘密鍵ファイルのうち、公開鍵ファイル(上記のコマンドだとdeploy_key.pub)の中身を、先ほど作成したリポジトリのDeploy Keysとして登録しましょう。
    作成したリポジトリのページから、「Settings」=>「Deploy keys」の順にクリックすれば、下記のような画面が表示されるはずです。
  4. 「Add Keys」ボタンをクリックすればOKです。

3. Herokuにgititをデプロイする

いよいよHerokuにデプロイです。
https://github.com/mietek/gitit に行って
をクリックしてください。
下記のような(恐らくHerokuファンにはお馴染みの)フォームが表示されるので、じゃんじゃん埋めちゃいましょう。

埋める内容は概ねデフォルトでいいのですが、以下重要な項目だけメモします。

App Name
そのままアプリのサブドメインになります。HaskellJP Wikiの場合は後で独自ドメインに書き換えるので、適当な文字列にして非公開にしましょう、とmasterqさんに言われましたので適当にしました。
Region
とりあえずUnited Statesで。Tokyoもやっぱり使いたいですけどね!
BUILDPACK_URL
Heroku自体触るのほぼ初めてだったので詳しく理解できてないのですが、ビルド用のスクリプト群が入っているリポジトリのURLを指定するみたいです。 何はともあれ、デフォルトであるmietekさんのリポジトリを指定しましょう。
BUILDPACK_SSH_PRIVATE_KEY
名前が紛らわしいですが、「2. Wikiデータ用のリポジトリを作って、deployキーを登録する」で作成した秘密鍵の中身をそのまんまコピペしましょう。
GITIT_GIT_URL
2. Wikiデータ用のリポジトリを作って、deployキーを登録する」で作成したリポジトリのURL(sshプロトコル)を指定しましょう。
HaskellJP Wikiの場合、git@github.com:igrep/haskell-jp-wiki.gitです。
GITIT_OAUTH_CLIENT_ID
文字通りGitHubのOAuthを利用する際のClient IDです。
1. GitHubのOAuth ApplicationとしてHaskellJP Wikiを登録する」で作成した際のClient IDをコピペしてください。
GITIT_OAUTH_CLIENT_SECRET
こちらも文字通りGitHubのOAuthを利用する際のClient Secretです。
先ほどの節で作成した際のClient Secretをコピペしてください。
GITIT_OAUTH_CALLBACK
こちらも読んで字のごとくユーザーの登録・認証の際に用いるOAuthのcallback用URLです。
デフォルト値から察せられるように、「CHANGE_ME」と書いてある部分をそのまま「App Name」に書き換えてもいいのですが、 ここでは「1. GitHubのOAuth ApplicationとしてHaskellJP Wikiを登録する」で書いた、「Authorization callback URL」という項目と同じ値を入力してください。 「<Wikiに設定する予定のドメイン>/_githubCallback」ですね。
httpとhttpsを間違えないようくれぐれもご注意ください。

ここまで入力できたらDeploy for freeをクリックしてください!いよいよ本当に本当のデプロイです!
とりあえず https://「App Name」で設定した値.herokuapp.com にアクセスして、gititが動いていることを確認しましょう。
こんな感じのページが表示されるはずです。

後はお使いのドメインのDNSレコードを編集して、https://「App Name」で設定した値.herokuapp.com をお使いのドメインのCNAMEとして設定するなりして、Herokuに対象のドメインを設定すればOKなはずです。 Herokuで独自ドメインを割り当てる(お名前.com)などを参考にどうぞ。 完了したらもろもろ動作確認してみましょう!お疲れ様でした!

次回!

明日のHaskell Advent Calendar 2014の記事はfumievalさんの番です。


  1. 誤解なきように申し上げますと、私はmasterqさんを責めるつもりは全くありません。彼はHaskellのよさとATSのよさを理解した上で、彼が作りたいものにはATSがより向いていると判断した、ただそれだけのことです。

  2. ちなみに、HaskellJP Wikiのものはhttps://github.com/igrep/haskell-jp-wikiにあります。

  3. 今のところ、秘密鍵を暗号化したりして安全性を高めるオプションはなさそうです…。


I'm a Haskeller Supported By Haskell-jp.