Nginx 使うには使うけど細かい設定はしていない1 Rubyist が Nginx だけで何かをする場合の設定をどうしたかのメモ。予め断っておくと、本当に今さらで内容も全然ない話。
単に開発環境でWebサーバが欲しい場合はLLでよい
はい。最初にものすごく身も蓋もないことを書くけど、Nginx を使う必要はない。むしろ準備に手間が掛かる。Python の SimpleHTTPServer とか Node.js の http-server とか、そんなんでいい。
動的にサーバサイドを書く? Rackでいいでしょ。言語もWebサーバも選べない? なるほど、頑張ろう。
Nginxはreverse proxyのために入れる
単純な Web アプリのためにはそんなに proxy 必要ないけど、一つ一つのアプリをシンプルに保とうとするほど、proxy は便利に使える。ということで Nginx を使うときにはほぼ proxy 必須という縛りでよいと思う。
必要な時だけ動くコマンドとして使いたい
Nginxはコマンドライン引数だけで動かすもんじゃないので設定ファイルを書く。こんな感じ。もちろん daemon off だ。
daemon off;
events {
}
http {
include mime.types;
sendfile on;
server {
listen 3000;
location / {
..
}
}
}
events section がないと怒られるけど、別に中身は要らない。mime.types は残念ながら必要で、これがないとブラウザが CSS とか無視してしまう。自分で作ってもいいし、適当に github から落としてきてもよい。
で、ここで大事なことの一つは log をファイルに紐付けないことで、
http {
access_log /dev/stdout;
error_log /dev/stderr debug;
}
※ error_log の debug 指定はお好みで。
しといてあげないと起動した Nginx のログはどこかに設定されているデフォルトのファイルに吐き出されていて terminal 上で全然確認できない。daemon off とこの設定はセットと思ってよい。
面倒なのは絶対パス
で、実際に設定をするわけだけど、やっかいなのは Document Root で、本当は起動時に相対パスで指定できるのがいちばんお手軽なんだけど、残念ながらそういう機能は Nginx にはないっぽい。まぁ daemon として動作する場合には間違いなくフルパスが必要なので、仕方ないっちゃ仕方ない。
こういうやつね。
http {
server {
location / {
root /path/to/root
}
}
}
で、じゃあどうするかというと、erb でワンクッション置いて埋め込むとよい。これは Heroku の Buildpack を参考にしていて、
#! /bin/sh
#
# Usage: start-nginx -c <config>
#
erb $2.erb > $2
nginx $@
という sh script を用意して、例えば
./start-nginx -c `pwd`/config/nginx.conf
のように動かす。
その nginx.conf.erb の中では
location / {
root <%= File.absolute_path(File.dirname(__FILE__) + '/../<root>) %>;
}
みたいなことを書いておけばおっけー。
要は
相対パス → 絶対パス変換を nginx に渡す前のどこかでやる
ってだけ。sh script の中で erb に渡す前に変換してやれば変換のコードは減るけど、 $@ で丸ごと引数渡してる部分を書き換えてやらないといけないのが面倒でとりあえずこんな感じにしてある。
まとめ
登場人物は以下の通り
- Nginx
- ERB
- erb を叩いたのち nginx を起動する sh script
- nginx.conf.erb
で、全然お手軽じゃない。
でも portable にしておかないと他人と共有できない2し、自分の手元でもうっかりプロジェクトの場所を動かしたら簡単に nginx.conf は壊れるものなので、この程度なら許容範囲かな?という辺りの面倒くささにしてある。