はじめに
僕は盲目的に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 process
とworker process
、cache manager process
の三つのプロセスが起動します。
その中のmaster process
以外を起動するユーザーを指定します。
master process
はroot
ユーザーで起動します。
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'...
ログのフォーマットを定義します。main
やltsv
などが選択でき、その後に出力したい値を定義します。
ここで定義したものを使用することができます。
参考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;
sendfile
がon
の時にこちらの設定をon
にすると、レスポンスヘッダとファイルの内容をまとめて送るようになります。少ないパケット数で効率良く送ることができます。
tcp_nodelay
tcp_nodelay on;
こちらは小さなパケットを待つことなく、そのまま送信するオプションです。待ちがないので早くなりますが、パケット数と送信量が増えます。
デフォルトはon
です。
tcp_nopush
と反対の動きをするそうですが、nginxはこの二つを組み合わせてもうまく動作するように実装されているようです。
うまく動かない場合はsendfile
、tcp_nopush
、tcp_nodelay
を全てoff
にするとうまく動く場合があります。
keepalive_timeout
keepalive_timeout 75;
HTTPの持続的な接続時間です。あまり長くするとコネクションを張りっぱなしになるスレッドが増えます。
0にするとoff
になります。
デフォルト75
。
keepalive_requests
keepalive_requests 100;
keepalive_timeout
が有効な時に同じクライアントからの要求が指定の数に達するとコネクションを切断します。
通常に使うならkeepalive_timeout 5
とkeepalive_requests 20
くらいで十分な気がする。
デフォルト100
。
set_real_ip_from
とreal_ip_header
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
Proxy
やロードバランサー
を経由した時に元のIPアドレスが失われてしまうことを防ぎます。
set_real_ip_from
でProxy
やロードバランサー
を指定して、Proxy
やロードバランサー
が保持している正しいIPアドレス
が記載されているヘッダーパラメータ
をreal_ip_header
に指定します。
X-Forwarded-For
が通例ですが、上位サーバーに依存するので上手くIPアドレスが取得できない場合は確認すること。
set_real_ip_from
は複数記載可能。
client_header_timeout
とclient_body_timeout
client_header_timeout 10;
client_body_timeout 10;
クライアントのリクエストヘッダとクライアントリクエストボディの読み込みのタイムアウト時間。
client_body_buffer_size
とclient_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_size
とlarge_client_header_buffers
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
通常は気にしなくてOK。
この定義を超えるヘッダーを送られた場合は414 (Request-URI Too Large) エラー
が発生します。
limit_conn
、limit_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
などのバックエンドサーバーを使用する時にupstream
でsocket
を指定する。(僕は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 server
がunicorn(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_page
、proxy_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;
エラーステータスに応じたページを表示します。
server
やlocation
ブロックでも使用できます。
proxy_intercept_errors
をon
にする必要があります。
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
は使用できない。)
listen
とserver_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.html
、hoge/index.html
、location @unicorn {}
の順番に探します。
location
ブロック
http {
server {
location / {
...
}
}
}
指定のロケーション(パスやファイル)の場合に適用されます。
以下のように正規表現で指定することもできます。
location ~ /\.(ht|svn|git) {
deny all;
}
上記の設定は.htaccess
や.svn
、.git
などのファイルにアクセスさせたくない場合に使用します。
stub_status
やallow
、deny
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;
なおallow
やdeny
に関してドメイン名
が使えるかどうかの記事は見当たらなかったため分かりませんでした。ただ、ドメイン名
を指定すると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:
- nginx最大パフォーマンスを出すための基本設定
- お名前.com VPS にNginxでWordPressを構築。設定の意味もまとめた
- nginx連載3回目: nginxの設定、その1
- nginxのパラメータチューニングとh2o
- LaravelとNginxの快速仕立て、キャッシュを添えないで…
- nginx でKeepAliveを設定してみる
- Nginx で Elastic Load Balancing などの Proxy の内側で正しい IP アドレスを取得する
- nginxのリクエストボディのバッファリングに関する問題とその改善策
- nginxパフォーマンスチューニング〜静的コンテンツ配信編〜
- ngx_http_core_module モジュール
- ngx_http_proxy_module モジュール
- ngx_http_gzip_module モジュール