2014年4月3日木曜日

nginxの設定でif文中のincludeがエラーになるので別の方法で設定する

nginx の設定で if文の中で include しようとするとエラーが起こります。具体的には、ドキュメントルート以下に存在しないファイルは別のURLのプロキシ向けに丸投げする設定を以下のように書きました。

location / {
  if (!-f $request_filename) {
    proxy_pass http://some-url;
    include /etc/nginx/proxy_params;
    break;
  }
}

上記設定を含んだ状態で起動しようとすると下記エラーが発生します。

[root@host]# service nginx start
Restarting nginx: nginx: [emerg] "include" directive is not allowed here in /etc/nginx/sites-enabled/foo:21
nginx: configuration file /etc/nginx/nginx.conf test failed

調べてみると、if 文の中ではincludeはできないようです。さらに、nginx において if は可能な限り避けろという話が見つかりました。予測できない動きをすることがあり、場合によってはクラッシュの危険もあるとか。

http://forum.nginx.org/read.php?2,123451,123462#msg-123462
http://wiki.nginx.org/IfIsEvil

ということで、別の方法を模索します。今回の目的なら代わりに try_files が使えます。

http://heartbeats.jp/hbblog/2012/04/nginx05.html

上記URLを参考に書いてみましょう。

location / {
  try_files $uri $uri/ @proxy;
}

location = / {
  try_files $uri @proxy;
}

location @proxy {
  proxy_pass http://some-url;
  include /etc/nginx/proxy_params;
}

location が "/" と完全一致の時の設定に注意してください。try_files に $uri/ が指定してあると、directory index を試みて 403 エラーになってしまいます。そのため "/" との完全一致で $uri/ を抜いた try_files を指定しておきます。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

0 件のコメント:

コメントを投稿