成果物
経緯
Emacs を使っている人は、日頃から
「あー Emacs でも HTTP サーバ立てられるんだし Heroku で起動してーなー」
と考えていると思います。
しかし Emacs ぐらいになると Heroku が標準サポートしている環境には含まれておらず、
いわゆるサードパーティ製 buildpack の導入が必要となります。
- 試しに使ってみたら、なんかエラー出た*2
- まあ直せばいいかーと思う
- buildpack の修正検証ってものすごいめんどくさいイメージ(ちゃんと調べてない)
- モチベーション消えた
みたいな人生を送っていました。
Heroku + Docker
そんなある日、もう一つの可能性である Docker を思い出しました。
Build and Deploy with Docker | Heroku Dev Center
リリースされた当時は
「好きな Docker イメージを Heroku で動かせるのかよすごい!!」
みたいな反応が多数(私も)だったのですが、実際には
- 「Heroku と同等の環境を Docker イメージとして配布する」
- 「その中で動作確認しろよ」
- 「(制限はあるが)そのままデプロイできるフローも作ったぜ」
的なものでした。
デプロイ方法もあるし、ドカドカデバックできるので、これで行こうと決めました。
そんなわけで作りました。
https://github.com/gongo/emacs-heroku-docker
概要は README を読んでもらうとして、つまり必要なことは
- 普段通り Emacs Lisp で Web アプリケーションを書く
- Cask ファイルを作成し、依存パッケージを書く
- Heroku ではお馴染の
Procfile
に、起動コマンドを書く - コンテナビルドしたり Heroku へリリースするためのファイルを作成
- docker build したあとのファイルを転送するため、リリースにも使われる
heroku docker:release
みたいな感じです。
試しに作ったのがこちら
https://emacs-heroku-docker-sample.herokuapp.com/
いつか消します
補足
heroku-docker でデプロイする時に注意するところ、備忘録も兼ねて
1. /app 以下のファイルしか転送されない
heroku docker:release
で Heroku にデプロイされるファイルは、awesome氏のポストにもある通り
/app以下をtgzで固めてcpコマンドでそれを取り出している.なのでDockerfileに独自の変更を加えるときは注意が必要で/app以下に依存をちゃんと含めるように書く必要がある.
という制限(仕様)となっています。
つまり、Dockerfile で素直に apt-get install emacs
とかやっても、Heroku 側には Emacs が入っていない slug が転送されてしまう、ということです。
なので今回はソースコードからコンパイルし、 /app/emacs
以下にインストールすることで依存を /app
以下に閉じ込めました。Cask についても同様。
2. 環境変数 export は /app/.profile.d/*
以下に書いておこう
上記のとおり heroku docker:release
で転送されるのは、コンテナ内の /app
以下だけ。つまり
ENV PATH /app/emacs/bin:$PATH
みたいなのを書いていても、docker run
した環境では使えますが Heroku 上には反映されません 。
ではどうするか。/app/.profile.d/
以下に、環境変数設定するファイルを書いておきます。
.profile.d Scripts | Heroku Dev Center
$HOME/.profile.d/
以下に置いたやつは Dyno 起動時に読まれるので、必要な処理はここに書いておきましょう。
ちなみに heroku-ruby では Dockerfile の ENTRYPOINT として init.sh というものを仕込んでいます。
#!/bin/bash for SCRIPT in /app/.profile.d/*; do source $SCRIPT; done exec "$@"
こうすることで
Procfile:
web: cask exec emacs -Q --batch -l app.el
docker run
時:
$ docker run `コンテナ名` cask exec emacs -Q --batch -l app.el
つまり
- Procfile に書くコマンドと docker run のコマンドを揃えることができる
- どちらもコンテナ起動時に
/app/.profile.d/*
以下を読んでくれる
という感じで、より Heroku の環境に近づけることができる、というわけです。
まとめ
heroku-docker を使うことで、buildpack よりも破壊再構築のサイクルを早く回せると思います。 どんどん作って最高のオレオレ cedar:14 にしよう!!
参考
- buildpack 探す時に利用
- docker + heroku に関する情報復習した
- Dockerfile の参考に
*1:https://github.com/technomancy/heroku-buildpack-emacs
*2:libgpmが無いとかなんとか