WordPressでNginxを使う時の設定(英語版のWordPressCodexの設定例の解説)

Nginxについて調べ、このブログに来る方が多いようなのでNginxのWordPressでの設定例を紹介。

WordPressの英語版Codexに掲載されているものです。2013/05/03現在、日本語版とは設定の仕方が違うようなので解説を入れてみようかと思います。

 

Main (generic) startup file

まずは、メインファイル(nginx.conf)です。

# Generic startup file.
// 起動ファイルですよ。

user {user} {group};
// Nginxを起動するユーザ名とグループを入れましょう。どちらもNginxが普通かな?

#ususally equal to number of CPU's you have. run command "grep processor /proc/cpuinfo | wc -l" to find it
worker_processes  2;
// サーバのCPUのコア数を入れましょう。設定例だと2コア。
// コア数の調べ方はコマンドで"grep processor /proc/cpuinfo | wc -l"を実行すればOK

error_log  /var/log/nginx/error.log;
// エラーログを吐き出す場所の指定(特にこだわりがなければそのままでOK)

pid        /var/run/nginx.pid;
// pidファイルを吐き出す場所の指定(特にこだわりがなければそのままでOK)

# Keeps the logs free of messages about not being able to bind().
#daemon     off;   

events {
    worker_connections  1024;
    // 1つのプロセスで処理できる最大接続数
}

http {
#  rewrite_log on; 
    // NginxのリライトモジュールによるURLの変更のログを出すか否か

    include mime.types;
    // MIME-typeの設定ファイルの読み込み
    
    default_type       application/octet-stream;    
    // デフォルトのMIME-typeの設定
    
    access_log         /var/log/nginx/access.log;   
    // アクセスログを吐き出す場所の指定
    
    sendfile           on;      
    // sendfile()APIを使うか否か(デフォルトはoff)
    
#  tcp_nopush         on;      
    // TCP_CORKソケットオプションを使うか否か(デフォルトはoff)
    
    keepalive_timeout  3;       
    // キープアライブのタイムアウトの設定
    
#  tcp_nodelay        on;      
    // TCP_NODELAYソケットオプションを使うか否か
    
#  gzip               on;  
    // レスポンスのコンテンツを圧縮するか否か
    
        #php max upload limit cannot be larger than this       
    client_max_body_size 13m;   
    // bodyサイズの制限(設定例だと13MB)
    
    index              index.php index.html index.htm;  
    // indexとして読み込むファイル

    # Upstream to abstract backend connection(s) for PHP.
    upstream php {
                #this should match value of "listen" directive in php-fpm pool
        server unix:/tmp/php-fpm.sock;
        // PHP-FPMでソケットを使う場合
        
#      server 127.0.0.1:9000;      
        // PHP-FPMでIPで指定する場合
    }

    include sites-enabled/*;
    // WordPressごとの設定ファイルの読み込み
}

 

Per Site configuration

WordPressのサイト用設定ファイルです。”sites-available”というディレクトリを作ってそこに入れてね。
複数用意すればバーチャルドメインもできるよ。

# Redirect everything to the main site. We use a separate server statement and NOT an if statement - see http://wiki.nginx.org/IfIsEvil ←詳しくはここ
// 以下mysite.comは自分のドメインに変更ね。

server {
        server_name  _;
        rewrite ^ $scheme://mysite.com$request_uri redirect;
}
// メインのサイトにはこの部分も設定しておこう。

server {
    server_name mysite.com;
    // 利用するドメインの指定だね。
    
    root /var/www/mysite.com;
    // ルートディレクトリの指定。上のドメインでリクエストするとこのディレクトリを読みに行くよ。

    include global/restrictions.conf;
    // アクセス制限用のファイルの読み込み

    # Additional rules go here.
    // 以下は自分の環境に合わせて読み込もう。

    # Only include one of the files below.
    include global/wordpress.conf;
    // WordPressをシングルインストール(通常のインストール)している場合
    
#  include global/wordpress-ms-subdir.conf;
    // WordPressをサブディレクトリ型マルチサイトでインストールしている場合
    
#  include global/wordpress-ms-subdomain.conf;
    // WordPressをサブドメイン型でインストールしている場合(Codexに詳細なし)
}

 

Global restrictions file

アクセスを制限する設定のファイルです。”global”というディレクトリを作ってその中に”restrictions.conf”という名前でファイル作成しよう。

# Global restrictions configuration file.
# Designed to be included in any server {} block.
location = /favicon.ico {
    log_not_found off;
    access_log off;
}
// ファビコンが見つからなくても気にしない
// ファビコンへのアクセスのログを出力しない

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}
// robots.txtはアクセス制限しませんよ
// 見つからなくても気にしない
// アクセスログは出力しません

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /. {
    deny all;
}
// .htaccess, .htpasswd, .DS_Store 等「.」で始まるファイルへは外部からアクセスさせません

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*.php$ {
    deny all;
}
// サブディレクトリ型マルチサイトでインストールした場合のuploadsとfilesのPHPファイルには外部からアクセスさせません。

 

General WordPress rules

WordPress用の設定ファイルです。これはシングル(通常の)インストールの場合。
“global”ディレクトリの中に”wordpress.conf”というファイル名で作成しよう。

# WordPress single blog rules.
# Designed to be included in any server {} block.

# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
    try_files $uri $uri/ /index.php?$args;
}
// URIに該当する静的ファイルがあった時はそれを表示。ない時はindex.phpにリダイレクト

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
// wp-adminへのリクエストをリダイレクト

# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
       access_log off; log_not_found off; expires max;
}
// CSSとかJSファイルとか画像ファイルなどの静的ファイルにExpiresヘッダーを期限MAXで付加。
// アクセスログも見つからない場合のエラーログも吐き出しませんよ

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;
// キャッシュ系のプラグインを使う場合の設定ファイルの読み込み。(Nginxでキャッシュさせればいらんのではないか?)

# Pass all .php files onto a php-fpm/php-fcgi server.
// PHPのファイルの設定
location ~ .php$ {
    # Zero-day exploit defense.
    # http://forum.nginx.org/read.php?2,88845,page=3
    # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
    # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
    try_files $uri =404;
    // PHP-FPMが動いてない場合404エラー

    fastcgi_split_path_info ^(.+.php)(/.+)$;
    // PHPファイルの形式を指定
    #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

    include fastcgi_params;
    // fastcgiのパラメータファイルの読み込み
    
    fastcgi_index index.php;
    // 適応させるインデックスファイル
    
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    // PHPのファイルの指定
    
#  fastcgi_intercept_errors on;
    // 4**や5**エラーのページを出すか、エラーページとして設定したページを出すか
    
    fastcgi_pass php;
    // PHPの場所。nginx.confで設定したPHPディレクティブ
}

シングルインストールの場合はここまででOK。次ページはマルチサイト(サブディレクトリ型)の場合ね。

 

Nginxで設定するとパーマリンク設定でindex.phpが出てしまう。これが気になる人は以下のコードをfunctions.phpに入れよう。

add_filter( 'got_rewrite', '__return_true' );

ちなみにNginx用のプラグインNginxHelperNginxCacheControllerなどを使えば追記しなくてもOKですよ。

 

WordPress Multisite Subdirectory rules

サブディレクトリ型マルチサイトの場合の設定ファイル。
“global”ディレクトリの中に”wordpress-ms-sudir.conf”としてファイル作成しましょう。

# WordPress multisite subdirectory rules.
# Designed to be included in any server {} block.

# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
        index index.php;
    try_files $uri $uri/ /index.php?$args;
}
// シングルインストールと変わらん

# Directives to send expires headers and turn off 404 error logging.
location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 24h;
    log_not_found off;
}
// Expiresヘッダーの設定。制限を24時間にしてある。

location ~ ^/files/(.*)$ {
          try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ;
          access_log off; log_not_found off; expires max;
}
// マルチサイトのサイトごとのファイルディレクトリの設定。Expiresヘッダーの制限MAX。$blog_idに関しては後述

#avoid php readfile()
location ^~ /blogs.dir {
        internal;
        alias /var/www/example.com/htdocs/wp-content/blogs.dir ;
        access_log off; log_not_found off;      expires max;
}
// マルチサイトのサイトごとのディレクトリの指定。Expiresヘッダーの制限MAX。内部リクエストとして処理。

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-ms-subdir-wp-super-cache.conf;
#include global/wordpress-ms-subdir-w3-total-cache.conf;
// キャッシュ系プラグインを使う場合の設定ファイル(やっぱりNginxでキャッシュさせれば、いらないんじゃないだろうか?)


# Rewrite multisite '.../wp-.*' and '.../*.php'.
if (!-e $request_filename) {
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;
    rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
    rewrite ^/[_0-9a-zA-Z-]+(/.*.php)$ $1 last;
}
// マルチサイトのリクエストリダイレクト設定。

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ .php$ {
    // PHPはシングルインストールと変わらんので略
    # Zero-day exploit defense.
    # http://forum.nginx.org/read.php?2,88845,page=3
    # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
    # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
    try_files $uri =404;

    fastcgi_split_path_info ^(.+.php)(/.+)$;
    #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#  fastcgi_intercept_errors on;
    fastcgi_pass php;
}

 

Better Performance for Static Files in Multisite

パフォーマンスを少しでも上げるために静的ファイルの設定を最適化しましょう。$blog_idの説明もここにあるよ。

map $http_host $blogid {
    default               0;

    example.com           1;
    site1.example.com     2;
    site1.com             2;
}

WordPressのサイトごとの設定ファイルのserverディレクションに上のようなコードを追加。
サイトのドメイン・URLとWordPressのサイトIDをマッピングする。
サイトを増やしたらURLとサイトIDをその都度追加していく。

 

これはめんどくさいのでプラグインを使っちゃいましょう。先ほども紹介したNginxHelperには、このマップを作ってくれる機能がついています。

これを使えば設定ファイルはこんな感じに

map $http_host $blogid {
    default               0;

    include /path/to/map.conf ;
}

/path/to/の部分はNginxHelperのプラグインディレクトリを指定してね。

 

ここまでやってマルチサイトの設定終わり。( ´ー`)フゥー...

次はFastcgiCache

 

Nginx fastcgi_cache

Nginxは独自でキャッシュを取る機能がついています。リバースプロキシで取る方法と、このFastcgiキャッシュと使う方法があります。
どちらでもいいですが、こっちのほうが設定が若干楽かな?

ロードバランシングとかをしたいと思ったらリバースプロキシを使ったほうがいいでしょう。
キャッシュの削除にはCachePurgeModuleを組み込む必要があるので注意。

 

Nginxの設定ファイルに追加

#move next 3 lines to /etc/nginx/nginx.conf if you want to use fastcgi_cache across many sites 
// nginx.confに追記

fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:500m inactive=60m;
// キャッシュしたファイルを置くディレクトリ、キャッシュレベル、キャッシュする容量の設定。

fastcgi_cache_key "$scheme$request_method$host$request_uri";
// キャッシュのキーの設定

fastcgi_cache_use_stale error timeout invalid_header http_500;
// 古いキャッシュを使う場合の設定。(設定例だとエラー、タイムアウト、500エラー)

 

サイトごとの設定ファイルのserverブロックに追加

#fastcgi_cache start
set $no_cache 0;
// キャッシュを開始

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
        set $no_cache 1;
}
// POSTリクエストはキャッシュしない

if ($query_string != '') {
        set $no_cache 1;
}
// GETパラメータがある場合はキャッシュしない

# Don't cache uris containing the following segments
if ($request_uri ~* '(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)') {
        set $no_cache 1;
}
// wp-adminとかwp-login.phpなどのURIへのリクエストはキャッシュしない

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* 'comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in') {
        set $no_cache 1;
}
// ログインユーザのリクエストはキャッシュしない

#note location{] block is simple now as caching is done on nginx's end
location / {
        try_files $uri $uri/ /index.php?$args;
}

 

PHPの設定箇所を変更

PHP周りの設定変更。

location ~ .php$ {
    try_files $uri =404; 
    include fastcgi_params;
    fastcgi_pass php;

    fastcgi_cache_bypass $no_cache;
        fastcgi_no_cache $no_cache;

    fastcgi_cache WORDPRESS;
    fastcgi_cache_valid  60m;
}

 

キャッシュをパージするための設定

NginxCachePurgeModuleが必要です。入れないと、手動でキャッシュファイル削除する羽目になりますよ。

location ~ /purge(/.*) {
    fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
} 

 

以上。簡単な解説付きの設定ファイルでした。
読みにくいと思うけど、ごめんちゃm(__)m

この記事を書いた人

たぬき@首席技監

アーシタンと蔵守の技術周り担当。主にワードプレス(WordPress)、サーバ管理なんかをやっています。