lighttpd(ライティー)で数独サーバーを作った話

tl;dr: Apacheで数独サーバーを作った話 - koba-e964の日記の続きです。

きっかけ

前回(Apacheで数独サーバーを作った話 - koba-e964の日記)の制作途中でいただいた以下のようなコメントがきっかけで、lighttpdでも作ってみることにしました。


完成品は変わらず
https://sparkle-sudoku-solver.herokuapp.com/
にあります。

概要

http://koba-e964.hatenablog.com/entry/2017/03/11/033819:title:前回Apache 2.4を使っていたところを、代わりにlighttpd (バージョンは現在apt-getで手に入る1.4.33)を使って作りました。
これにより、完成品のDocker imageの大きさが628MB (Apache版) -> 356MB(lighttpd版)になり、大幅に軽量化できました。
https://sparkle-sudoku-solver.herokuapp.com/から遊べます。

バージョン情報:

root@87a939323768:/# lighttpd -v
lighttpd/1.4.33 (ssl) - a light and fast webserver
Build-Date: Jan 28 2014 17:26:04
root@87a939323768:/# date
Sun Mar 12 15:19:00 UTC 2017

imageのサイズ:

$ docker images sparklenumberplace_lighttpd
REPOSITORY TAG IMAGE ID CREATED SIZE
sparklenumberplace_lighttpd latest 5f5683b70260 10 hours ago 356 MB
$ docker images sparklenumberplace_web
REPOSITORY TAG IMAGE ID CREATED SIZE
sparklenumberplace_web latest 797b93561b96 23 hours ago 628 MB

記事執筆時点でのソース:
GitHub - koba-e964/sparkle-number-place at a30029f7cfc4897b9fbcc2eaa26f52356512ca5e

ハマったポイント

  • 起動スクリプト(start-lighttpd.sh)を/tmp/以下において、CMDで実行しようとしたら、手元では動くもののheroku上では動かないという事態になりました。これはおそらく、docker imageのビルド時に見える/tmp/とheroku上で書き込みできる/tmp/が異なる場所を指しているためだと思われます。(herokuは一時ファイル保存のため、/tmp/以下にのみファイルの書き込みを許しています。 *1 参考: Stack Overflowの質問)
    結局起動スクリプトを/tmp/ではなく/opt/に配置することにして解決しました。
  • Dockerfileの仕様で、Dockerfileの配置してあるディレクトリの外のファイルは参照できないのですが*2、この仕様のせいでサーバーごとにディレクトリを分割することと共通のファイルを再利用することが両立できませんでした。ここではDockerfile.*という名前のファイルにdocker scriptを書き、docker-compose.ymlでサーバーごとに参照するDockerfileを変えることにしました。なおこの方法だとheroku container:pushができない(Dockerfileという名前のファイルを参照するため)ので、push用のスクリプトpush-lighttpd.shを用意することにしました。*3

今後やりたいこと

  • lighttpd版で使うLinux distributionを特に何も考えずUbuntuにしましたが、他のdistributionだとどのくらい軽量化できるのかが気になります。またApache版はDebianだったので、Debianでもやってみて公正な比較をしてみたいと思っています。
  • 前回の「今後やりたいこと」はまだできていないので、それらにも取り組みたいと思っています。

*1:heroku上のファイルシステムはephemeralなので、一度作ったテンポラリファイルがずっと残っていることを前提にプログラミングをしてはいけません。(dynoが停止または再起動するタイミングで消えます。) またファイルシステムはdynoごとに作られるので、/tmp/を介して別のdynoと通信をすることはできません。参考: 公式Herokuで一時ファイル保存 - 木木木

*2:GitHubのissueで議論がされているので、興味があったら是非読んでみてください。

*3:DockerfileをDockerfile.lighttpdへのsymbolic linkにして、herokuの目を欺くやり方です。こんな小手先の対策とりたくなかったです…