nginx
unicorn

Nginx設定のまとめ

More than 3 years have passed since last update.


はじめに

僕は盲目的にunicornを起動するためだけにnginxを使っていて、設定ファイルの内容とかをほとんど知らない。

なので、ここにnginxの設定内容をまとめる事で自分自身が覚えようと思う。

普段使う大抵の設定は記載しているつもりです。

記載内容は実際に試したものと試してないものが混在してるので、誤った設定などがあるかもしれないのでその辺はコメントでご指摘いただけると助かります。


インストール

インストールについては僕が書くより他の人の記事を見た方がいいと思う。

centosに入れるなら以下の記事が参考になる。

またchefでインストールする場合は以下の記事が役にたつ。

chefの使い方に関しては僕の記事を参考にしてもらえれば幸いです。


コマンド

以下のコマンドが使える。

$ /etc/init.d/nginx -h

Usage: nginx {start|stop|restart|condrestart|try-restart|force-reload|upgrade|reload|status|help|configtest}


起動

とりあえず、起動コマンドだけ書いておく。

$ /etc/init.d/nginx start

# もしくは
$ service nginx start


設定ファイル

インストール後/etc/nginx/nginx.confにnginxの設定ファイルが配置されている。

今回はこちらのファイルに定義できる事をまとめてみる。(メモってみる。)


user

user nginx;

nginxを起動するとmaster processworker processcache manager processの三つのプロセスが起動します。

その中のmaster process以外を起動するユーザーを指定します。

master processrootユーザーで起動します。


worker_processes

worker_processes auto

worker_processes 2

Nginxがシングルスレッドで動作するため、コア数に合わせて設定しておく。

コア数よりも多くの値を指定しても問題がないらしい。

autoに指定するとコア数を設定してくれる。

なお、コア数は以下のコマンドで調べれる。

$ grep processor /proc/cpuinfo |wc

CPUの割り当てを明示的に使用する場合は以下を使用する。

worker_cpu_affinity 01 11

参考URL:

Nginxのworker_processesとworker_cpu_affinity


worker_rlimit_nofile

worker_rlimit_nofile  4096;

プロセス毎のファイルディスクリプタ上限数。

後述するworker_connectionsの3〜4倍くらいが目安になる。

なお、システムのファイルディスクリプタは以下のコマンドで確認が取れる。

$ cat /proc/sys/fs/file-max

参考URL:

nginx で Too many open files エラーに対処する


error_log

error_log /var/log/nginx/error.log;

nginxは動いたけどrailsまで届いてないみたい・・・などの時に真っ先にみるログの場所ですw(もしくはaccess_log。後述)

デフォルトのままで良いかと思います。

この定義はhttpやserverブロックなどでも使用できます。


pid

pid /var/run/nginx.pid;

このファイルの中身をあまり見ることはないですが、PIDが格納されている。

ついつい以下のコマンドで確認してしまう・・・。

$ ps aux | grep nginx

root 31866 0.0 0.0 65724 276 ? Ss 09:55 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 31868 0.0 0.2 67040 1544 ? S 09:55 0:00 nginx: worker process
nginx 31869 0.0 0.0 65944 336 ? S 09:55 0:00 nginx: cache manager process


eventsブロック

events {

...
}

eventモジュールの定義ができます。

以下の三つの項目が...の中に記載できます。


worker_connections

worker_connections 512;

一つのワーカーが同時に処理できる接続数です。


multi_accept

multi_accept on;

onの場合、複数の接続をすべて1度に受け入れる。


use

use epoll

「Linuxカーネル2.6以上の場合はepoll、BSDの場合kqueue」とのこと。通常は上記の設定で問題ないと思う。


httpブロック

http {

...
}

Webサーバーとして使用するメインとなる処理。


server_tokens

server_tokens off;

エラーページのフッタに Nginx のバージョンを表示するかどうかの設定。

セキュリティ上offの方が望ましい。


include /etc/nginx/mime.types;

include       /etc/nginx/mime.types;

MIMEタイプと拡張子の関連付けを定義したファイルを読み込みます。

types {

text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
...
}

このような形で、MIMEタイプがまとめられてます。


default_type

default_type  application/octet-stream;

上述のmime.typesで拡張子からMIMEタイプを決定できなかったときに、ここで指定したMIMEタイプが適応されます。

デフォルトの設定値はtext/plainです。


log_format

log_format main 'time:$time_iso8601\t'...

log_format ltsv 'time:$time_iso8601\t'...

ログのフォーマットを定義します。mainltsvなどが選択でき、その後に出力したい値を定義します。

ここで定義したものを使用することができます。

参考URL:


access_log

access_log /var/log/nginx/access.log ltsv;

上記で指定したlog_formatを最後に指定します。

この定義はserverブロックなどでも使用できます。

access_log off;

と設定することもできます。


charset

charset UTF-8;

レスポンスヘッダーにContent-Type: text/html; charset=UTF-8などのcharsetを付与する。


sendfile

sendfile on;

OSが提供しているsendfileを使用するかどうかを指定します。

sendfileを使用するとnginx内部でファイルの読み込みと送信を行わずカーネル空間内で行ってくれるため効率良くファイルを送信できます。(jsファイルやcssファイルの転送に使用?)

デフォルトの設定値はoffです。


tcp_nopush

tcp_nopush on;

sendfileonの時にこちらの設定をonにすると、レスポンスヘッダとファイルの内容をまとめて送るようになります。少ないパケット数で効率良く送ることができます。


tcp_nodelay

tcp_nodelay on;

こちらは小さなパケットを待つことなく、そのまま送信するオプションです。待ちがないので早くなりますが、パケット数と送信量が増えます。

デフォルトはonです。

tcp_nopushと反対の動きをするそうですが、nginxはこの二つを組み合わせてもうまく動作するように実装されているようです。

うまく動かない場合はsendfiletcp_nopushtcp_nodelayを全てoffにするとうまく動く場合があります。


keepalive_timeout

keepalive_timeout 75;

HTTPの持続的な接続時間です。あまり長くするとコネクションを張りっぱなしになるスレッドが増えます。

0にするとoffになります。

デフォルト75


keepalive_requests

keepalive_requests 100;

keepalive_timeoutが有効な時に同じクライアントからの要求が指定の数に達するとコネクションを切断します。

通常に使うならkeepalive_timeout 5keepalive_requests 20くらいで十分な気がする。

デフォルト100


set_real_ip_fromreal_ip_header

set_real_ip_from   10.0.0.0/8;

real_ip_header X-Forwarded-For;

Proxyロードバランサーを経由した時に元のIPアドレスが失われてしまうことを防ぎます。

set_real_ip_fromProxyロードバランサーを指定して、Proxyロードバランサーが保持している正しいIPアドレスが記載されているヘッダーパラメータreal_ip_headerに指定します。

X-Forwarded-Forが通例ですが、上位サーバーに依存するので上手くIPアドレスが取得できない場合は確認すること。

set_real_ip_fromは複数記載可能。


client_header_timeoutclient_body_timeout

client_header_timeout 10;

client_body_timeout 10;

クライアントのリクエストヘッダとクライアントリクエストボディの読み込みのタイムアウト時間。


client_body_buffer_sizeclient_body_temp_path

client_body_buffer_size      32k;

client_body_temp_path /dev/shm/client_body_temp 1 2;

受け付けたリクエストのボディはclient_body_buffer_sizeまではメモリで保持し、それ以上はclient_body_temp_pathへファイルとして吐き出します。

nginxのリクエストボディのバッファリングに関する問題とその改善策に書かれてますがclient_body_buffer_sizeが定義されていても以下のようにserverブロックにproxy_request_buffering offを指定すればその条件ではバッファリングされなくなります。

server {

listen 80;
server_name example.com;

location /upload {
proxy_request_buffering off;
proxy_pass http://upload_backend;
}
}


client_max_body_size

client_max_body_size 1m;

クライアントから送られてくるボディのマックス値です。これ以上のサイズが送られてくると413(Request Entity Too Large)エラーが発生します。


client_header_buffer_sizelarge_client_header_buffers

client_header_buffer_size 1k;

large_client_header_buffers 4 8k;

通常は気にしなくてOK。

この定義を超えるヘッダーを送られた場合は414 (Request-URI Too Large) エラーが発生します。


limit_connlimit_conn_zone

limit_conn_zone $binary_remote_addr zone=addr:10m;

limit_conn addr 100;

同時接続数を制限します。

Dos攻撃等を防ぎたい方は以下のサイトが参考になります。

参考URL:

Nginxで使える制限一覧


proxy関連

proxy_buffering on;

proxy_buffer_size 8k;
proxy_buffers 100 8k;
proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=CACHE:512m inactive=1d max_size=60g;

リバースプロキシとして使用する場合の設定です。

この辺りは僕の理解を超えてます・・・。(unicornを使う場合はここの設定をしっかり設定する必要がある気がするけど・・・。)

Nginx をリバースプロキシ(キャッシュ) として使ってみたが参考になるかと思います。


gzip関連

gzip on;

gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied expired no-cache no-store private auth;
gzip_vary off;
gzip_types text/plain
text/css
text/xml
...
application/json;
gzip_min_length 1000;
gzip_disable "MSIE [1-6]\.";

レスポンスにgzipを使用する場合にonにします。サーバー間の転送量を抑えることができます。

以下、実際に使う時に変更するものだけを軽く記載。

gzip_typesで指定しているタイプのファイルのみが有効になります。

gzip_proxiedで指定しているリクエストタイプに対してのみ有効になります。

gzip_min_lengthよりも少ないレスポンスはgzip化しません。圧縮コストの方が高くなってしまいます。

gzip_disable、、、とりあえずIE6以下はgzip対象外にしましょう。


open_file_cache関連

open_file_cache max=100 inactive=10s;

open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

nginxパフォーマンスチューニング〜静的コンテンツ配信編〜が参考になります。

ファイルディスクリプタやサイズ、更新時間といった情報をキャッシュすることができます。


server_names_hash_bucket_size

server_names_hash_bucket_size 64

とりあえず64を指定しておけばいい気がします。

nginxのエラー“increase server_names_hash_bucket_size”の対処方法


types_hash_max_size

types_hash_max_size 1024;

タイプのハッシュテーブルのsizeの最大値を設定します。


types_hash_bucket_size

types_hash_bucket_size 64;

タイプのハッシュテーブルのためのbucketサイズを設定します。

この辺はデフォルト値でいい気がする。


listen

listen 80 default_server;

nginxをそのまま使う場合はhttpブロック内に記載しますが、通常はバーチャルホストで使用すると思うのでここに記載することはあまりないと思う。

なおdefault_serverをつければマッチしない場合に使われる。


server_name_in_redirect

server_name_in_redirect off;

リダイレクト時にサーバー名をヘッダーに埋め込むかどうかですが、onにすることは基本的にないと思います。

offにすればクライアントがリクエストしてきたHostヘッダの文字列がLocationのホスト名に使われます。


port_in_redirect

port_in_redirect on;

onならリダイレクト時、URL の末尾にポート番号を付与する。


upstream

upstream unicorn {

server unix:/path/current/tmp/sockets/unicorn.sock fail_timeout=0;
}

upstream server_com {
server 127.0.0.3:8000 weight=5;
server 127.0.0.3:8001 weight=5;
server 192.168.0.1:8000;
server 192.168.0.1:8001;
}

server {
listen 80;
server_name unicorn;

root /path/current/public;

location @unicorn {
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header Host $http_host;
proxy_pass http://unicorn;
}
}

server {
listen 80;
server_name server.com;

location / {
proxy_pass http://server_com;
}
}

unicornなどのバックエンドサーバーを使用する時にupstreamsocketを指定する。(僕はpidを指定してしまい動かなかったという超恥ずかしい事をした事がある・・・。)

また、他のサーバーを複数指定してロードバランスする事もできる。


proxy_set_header

proxy_pass http://127.0.0.1:3000;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header X-Powered-By;
proxy_ignore_headers Expires;

バックエンドサーバに送信するヘッダを定義し直す。

大体上記の設定で問題ないと思う。

リバースプロキシを使う場合はproxy_passは先に定義する必要がある。

nginxのproxy_set_headerの設定場所

※Unicornなどのソケット通信の場合はproxy_passを後ろに書いても問題ないっぽい。

proxy_hide_headerはヘッダー情報を消します。セキュリティ上クライアントに漏らしたくない情報を消します。

proxy_ignore_headersで指定した値は無視する。上記の例ではExpiresを無視するのでキャッシュされない・・・。(よくわかってない)

proxy_connect_timeout

proxy_send_timeout
proxy_read_timeout

などの設定もあります。

詳しくはお名前.com VPS にNginxでWordPressを構築。設定の意味もまとめたがわかりやすかったです。

と思ったのですが、この設定は結構重要なので簡単に説明しておきます。

nginxに設定されているupstream serverunicorn(Rails)だとした場合を例に説明します。


proxy_connect_timeout

nginxからunicornへコネクションを張るタイムアウト時間です。

通常は1秒とかでコネクションは張られるはずです。

最大75秒ですが、10秒とかの設定で十分だと思います。


proxy_send_timeout

nginxからunicornに対してデータを送信する際のタイムアウト値です。

送信で時間がかかることは無いので、これも10秒とかの設定で十分だと思います。

(どんなに大きなファイルを送信してもHTTPリクエストで考えると数秒で終わると思います。)


proxy_read_timeout

この値が一番重要です。

渡されたファイル(データ)をもとにunicornが処理をすると思いますが、この値の設定を過ぎるをコネクションが切られてしまいます。

なのでunicornに処理をさせる場合に想定される最大時間を設定します。

巨大CSVの処理のように時間が掛かる場合はこの値を長めにとっておきましょう!)

また、unicornにもタイムアウトの設定がありますのでunicornのタイムアウトよりも長い時間設定しておく必要があります。


proxy_redirect

proxy_redirect off;

バックエンドサーバがリダイレクトした時の Location ヘッダ。on なら proxy_pass をホスト名としてリダイレクト。off ならサーバの指示通りにリダイレクト。


error_pageproxy_intercept_errors

proxy_intercept_errors on;

error_page 404 /404.html;
error_page 403 =404 /notfound.html; # 403の場合404に変換される。
error_page 500 502 503 504 /50x.html;

エラーステータスに応じたページを表示します。

serverlocationブロックでも使用できます。

proxy_intercept_errorsonにする必要があります。


include /etc/nginx/vhost.d/*.conf;

include /etc/nginx/vhost.d/*.conf;

serverなどを別のファイルに定義する場合は上記の設定を行います。

これによって指定フォルダのファイルが読み込まれます。

(httpブロックに記述すれば、httpブロックに展開されるっぽいので個別ファイル内ではhttp{}を記述する必要はない。)


serverブロック

http {

server {
...
}
}

nginxでバーチャルホストの運用をする際に使用します。

serverで区切った単位でバーチャルホストが作成されます。

httpブロック内に記述します。

serverブロック内の記述は大体locationでも使用できます。

listen,server_name,rootは使用できない。)


listenserver_name

listen 80 default_server;

server_name localhost;

このバーチャルホストにアクセスするための情報です。

listenはIPアドレスなども指定できますが、僕はポート番号しか指定した事がありません。

default_serverを指定すると他の全てにマッチしない場合に使われるサーバーになります。

また、listenには様々なオプションがあるようです。こちらを参照ください。

server_nameは指定のドメインの場合に対象となります。

このケースではhttp://localhost:80の場合に適用されます。


root

root /path/public

このserverブロック内で使用するルートディレクトリを指定します。


rewrite

rewrite /(.*)/index.html $1.html permanent;

リダイレクトさせたい場合に使用します。


satisfy,auth_basic

satisfy any;

auth_basic "basic authentication";
auth_basic_user_file /etc/nginx/.htpasswd;

satisfyは一部のアドレスにBasic認証をかけない場合などに使います。こちらのサイトがわかりやすかったです。

auth_basicは認証名を表示させます。

auth_basic_user_fileにパスワードファイルを指定します。


try_files

try_files $uri $uri.html $uri/index.html @unicorn;

指定のファイルが存在するかを左から探しに行きます。

例えばhttp://***/hogeでアクセスした場合はhoge.htmlhoge/index.htmllocation @unicorn {}の順番に探します。


locationブロック

http {

server {
location / {
...
}
}
}

指定のロケーション(パスやファイル)の場合に適用されます。

以下のように正規表現で指定することもできます。

location ~ /\.(ht|svn|git) {

deny all;
}

上記の設定は.htaccess.svn.gitなどのファイルにアクセスさせたくない場合に使用します。


stub_statusallowdeny

stub_status on;

access_log off;
allow 127.0.0.1;
deny all;

stub_statusが指定されたロケーションにアクセスすると現在の接続数などの情報がみれます。

通常外に公開する事はありません。

allowを指定した場合は対象のIPからのアクセスを許可します。ここでは127.0.0.1を許可してます。

denyを指定した場合は対象のIPからのアクセスを禁止します。ここでは全てのアクセスを禁止してます。

nginxは上から評価されるため、上記のケースの場合はallow 127.0.0.1が先に評価されるため127.0.0.1のアクセスのみが適用されます。

もし、以下のように逆に記述してしまうと全てのIPアドレスからのアクセスが拒否されます。(Apacheとは違うので注意。)

deny all;

allow 127.0.0.1;

なおallowdenyに関してドメイン名が使えるかどうかの記事は見当たらなかったため分かりませんでした。ただ、ドメイン名を指定するとDNSサーバーへアクセスして判断する必要が出てくるはずなので基本的には行わないと思います。


expires

expires 10d;

ブラウザキャッシュを使用する場合に使用する。上記の例だと10日はブラウザのキャッシュを使用する。


add_header

add_header Cache-Control public;

レスポンスヘッダーにつける値を設定します。

以下のURLが参考になります。


break

break;

これ以降のrewrite処理を行わない。

参考URL:

nginx rewriteのlastとbreakの違い


internal

error_page 404 /404.html;

location /404.html {
internal;
}

内部リダイレクトにしか使いたくない場合に使用します。

この例では、直接/404.htmlページを見ることができません。


参考URL: