以前にVPSにnginxをインストールしてWordpress用のバーチャルホストを設定する記事を書きましたが、改めてWordpress用のnginxの設定をまとめておきたいと思います。
インストール方法等は飛ばしますので、必要な方は以前の記事もご覧ください。
PHPを稼働させる
まず、PHPを使えるようにします。
index index.php;
location ~ .*\.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
nginxのインストール環境によっては、fastcgiのスクリプトを自分で作成する必要があります。
動かない場合はそのへんを確認するといいかもしれません。
パーマリンク設定
パーマリンク設定でURL書き換えを行っている場合は下記が必要です。
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
# マルチサイトにしている場合は以下も必要
rewrite ^.*/files/(.*) /wp-includes/ms-files.php?file=$1;
.htaccess対策
WordPressやプラグインは、Apacheをベースに考えているので、サーバーがNginxでも勝手に .htaccess を生成する事があります。
当然その内容はNginx用に変換する必要があるのですが、不用意に生成された場合に、Nginxでは.htaccessが丸見えになってしまいますので、その対策をします。
location ~ /\.ht { deny all; }
gzip圧縮転送設定
htmlやcss、js等のテキストファイルをgzip圧縮転送させる設定です。対象ファイルをMIMEタイプで指定します。ここでは多めに設定してみてるので、環境に合わせて変更してください。
[参考: HttpGzipModule]
gzip on;
gzip_http_version 1.0;
gzip_min_length 1000;
gzip_comp_level 1;
gzip_proxied expired no-cache no-store private auth;
gzip_vary on;
gzip_types text/plain
text/xml
text/css
text/javascript
image/x-icon
application/xml
application/rss+xml
application/json
application/x-javascript;
gzip_disable "MSIE [1-6]\.";
gzip_disable "Mozilla/4";
古いブラウザ相手にgzip圧縮転送すると不安定な事があるらしいので、条件付けて gzip_disable させてます。
また、うちのサーバは省メモリのVPSなのと、Wordpressを使う場合、サーバ負荷の原因の多くは転送量よりもCPU負荷かと思うので、gzip_comp_level は1にしてます。
ブラウザキャッシュを有効にする
ファイルの送信ヘッダに有効期限をつけることで、ブラウザ側でのキャッシュを期待できます。
ここでは、ファイル自体が存在する静的ファイルすべてに有効期限を設定します。
[参考: HttpHeadersModule]
location / {
if (-f $request_filename) {
expires 30d;
add_header Pragma "public";
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
proxy cacheを有効にする
nginxをリバースプロキシサーバとして設定します。
[参考: HttpProxyModule]
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=czone:10m max_size=200m inactive=1d;
proxy_temp_path /var/tmp/nginx;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;
proxy_set_header Host $http_host;
proxy_set_header X-Remote-Addr $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
upstream www_domain_com {
ip_hash;
server 127.0.0.1:8080;
}
server {
listen 80;
server_name www.domain.com;
access_log /var/log/access.log;
error_log /var/log/error.log;
location /wp-admin { proxy_pass http://www_domain_com; }
location ~ .*\.php { proxy_pass http://www_domain_com; }
location / {
if ($http_user_agent ~* '(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)') {
set $mobile 1;
}
if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
set $mobile 2;
}
if ($http_cookie ~* "comment_author_[^=]*=([^%]+)%7C|wordpress_logged_in_[^=]*=([^%]+)%7C") {
set $do_not_cache 1;
}
proxy_no_cache $do_not_cache;
proxy_cache_bypass $do_not_cache;
proxy_cache czone;
proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
proxy_pass http://www_domain_com;
}
}
上記の記述で以下のような動作になります。
- 10M〜200Mまでのキャッシュを1日保存。
- コンテンツ取得は10分間、移転は1時間、エラーは1分間、再チェックなし
- 管理画面へのアクセスはキャッシュサーバー素通り
- 携帯電話とスマートフォンとPCで別々のキャッシュを作成
- Cookieはキャッシュ対象外
次に元のWordpressをインストールしてあるサーバ設定の、listen と server_name を変更して、アクセスログの設定を削除します。
server {
listen 8080;
server_name _;
… その他の設定
}
proxy cacheのクリア
ngx_cache_purge モジュールが Nginx にインストールされている場合は、強制キャッシュクリアが使えます。
普段はキャッシュの再チェック時間(上記だと10分間)で更新されるので、手動でキャッシュクリアする必要はあまりありませんが、非常時用に強制的にキャッシュクリアする手段だけ作っておくと安心です。
location ~ /purge(/.*) {
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
この場合、$mobile変数を利用するので、前に記載したコードを、一つ上の階層のserverディレクティブに移す必要があります。
server {
...
if ($http_user_agent ~* '(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)') {
set $mobile 1;
}
if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
set $mobile 2;
}
...
}
モジュールが無い場合は、キャッシュディレクトリを全部削除するしか方法がありません。
# sudo rm -f -R /var/cache/nginx/*
nginx.conf 設定例
これまでの内容を入れた、nginx.conf の設定例です。
それぞれを合わせたので、前記とは異なる記述になっている箇所もあります。
user apache;
worker_processes 2;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nodelay on;
keepalive_timeout 45;
server_tokens off;
# gzip
gzip on;
gzip_http_version 1.0;
gzip_min_length 1000;
gzip_comp_level 1;
gzip_proxied expired no-cache no-store private auth;
gzip_vary on;
gzip_types text/plain
text/xml
text/css
text/javascript
image/x-icon
application/xml
application/rss+xml
application/json
application/x-javascript;
gzip_disable "MSIE [1-6]\.";
gzip_disable "Mozilla/4";
# Proxy Cahe
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=czone:15m max_size=100m inactive=120m;
proxy_temp_path /var/tmp/nginx;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;
# set header
proxy_set_header Host $http_host;
proxy_set_header X-Remote-Addr $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
upstream www_domain_com {
ip_hash;
server 127.0.0.1:8080;
}
server {
listen 80;
server_name www.domain.com;
access_log /var/log/access.log;
error_log /var/log/error.log;
if ($http_user_agent ~* '(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)') {
set $mobile 1;
}
if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
set $mobile 2;
}
location /wp-admin { proxy_pass http://www_domain_com; }
location ~ .*\.php { proxy_pass http://www_domain_com; }
location / {
if ($http_cookie ~* "comment_author_[^=]*=([^%]+)%7C|wordpress_logged_in_[^=]*=([^%]+)%7C") {
set $do_not_cache 1;
}
proxy_no_cache $do_not_cache;
proxy_cache_bypass $do_not_cache;
proxy_cache czone;
proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
proxy_pass http://www_domain_com;
}
location ~ /purge(/.*) {
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
}
server {
listen 8080;
server_name _;
root /var/www;
index index.html index.php;
charset utf-8;
location / {
if (-f $request_filename) {
expires 30d;
add_header Pragma "public";
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
try_files $uri $uri/ /index.php?q=$uri&$args;
}
rewrite ^.*/files/(.*) /wp-includes/ms-files.php?file=$1;
location ~ .*\.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht { deny all; }
}
}
追記
- 2011.08.19 設定パラメータの一部を調整しました。
- 2011.11.01 purgeの設定を見直しました。