お名前.com VPS にNginxでWordPressを構築。設定の意味もまとめた

2013年6月22日

WordPress

お名前.com VPS メモリ2G プランに Nginx で WordPress を構築するメモ、第10回目。前回は、Nginx と PHP-FPM をインストールするところまでやりました。

WordPress
お名前.com VPS にNginxとPHP-FPMをインストール

お名前.com VPS メモリ2G プランに Nginx で WordPress を構築するメモ、第9回目。前回はさくら ...

続きを見る

今回は、Nginx で WordPress を動作させ、リバースプロキシを有効にします。設定の意味も出来る限り調べ、まとめました。

目次

  1. Nginx 基本設定
  2. VirtualHost 設定
  3. WordPress ファイルの 所有者を nginx に変更
  4. WordPress の functions.php で expires header を出力
  5. WordPress の 404 ページをキャッシュする
  6. アクセスログを確認する
  7. キャッシュ系プラグインの利用状況

Nginx 基本設定

Nginx 全体の設定は /etc/nginx/nginx.conf で設定します 。設定は さくらVPS512で、Yahoo!砲食らっても WordPress を平常運転させるための設定 | dogmap.jp のサイトを参考にさせていただきました。一部 お名前.com 用にカスタマイズしていますが、基本的にはこちらのサイトの設定と同じです。

Nginx、PHP-FPM のインストールが済んでいない方は PHP-FPM のインストールは お名前.com VPS にNginxとPHP-FPMをインストール をどうぞ。

ポイントは以下の通り。

  • ワーカプロセスは 3 個。
  • Gzip 有効。
  • リバースプロキシキャッシュの有効期間は 1日。

/etc/nginx/nginx.conf

user              nginx nginx;
worker_processes  3;
worker_rlimit_nofile 4096;
worker_cpu_affinity 001 010 100;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    multi_accept off;
    worker_connections  1024;
    use epoll;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" $upstream_cache_status'
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  backend '$http_x_forwarded_for - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent"';
    access_log  /var/log/nginx/access.log  main;
    server_tokens     off;
    server_name_in_redirect off;
    port_in_redirect  off;
    client_max_body_size    16m;
    client_body_buffer_size 256k;
    sendfile        on;
    tcp_nopush      on;
    keepalive_timeout   2;
    gzip_static       on;
    gzip              on;
    gzip_http_version 1.0;
    gzip_vary         on;
    gzip_comp_level   2;
    gzip_types        text/plain text/xml text/css text/javascript
                      application/xhtml+xml application/xml
                      application/rss+xml application/atom_xml
                      application/javascript application/x-javascript
                      application/x-httpd-php;
    gzip_disable      "MSIE [1-6]\.";
    proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=one:32m max_size=512m inactive=1d;
    proxy_temp_path   /var/tmp/nginx;
    proxy_cache_key   "$scheme://$host$request_uri";
    proxy_set_header  Host               $host;
    proxy_set_header  X-Real-IP          $remote_addr;
    proxy_set_header  X-Forwarded-Host   $host;
    proxy_set_header  X-Forwarded-Server $host;
    proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header  Accept-Encoding    "";
    proxy_connect_timeout 5;
    proxy_send_timeout 10;
    proxy_read_timeout 120;
    proxy_hide_header X-Pingback;
    proxy_hide_header X-Powered-By;
    proxy_hide_header Etag;
    proxy_hide_header Vary;
    proxy_cache_use_stale timeout invalid_header http_500 http_502 http_503 http_504;
    proxy_cache_lock on;
    proxy_cache_lock_timeout 5s;
    upstream backend {
        server unix:/var/run/nginx-backend.sock;
    }
    upstream phpfpm {
        server unix:/var/run/php-fpm/php-fpm.sock;
    }
    include /etc/nginx/conf.d/*.conf;
}

Main モジュール

user
Nginx ワーカプロセスの実行ユーザとグループ。PHP-FPM の実行ユーザと同じに。

worker_processes
ワーカプロセスの数。CPU コア数と同じ 3 に。

worker_rlimit_nofile
ワーカプロセスが同時に使えるファイル数。CentOS のファイルオープン数の上限を超えないように。上限は、$ ulimit -a | grep 'open files' コマンドで確認できる。

worker_cpu_affinity
ワーカプロセスが使用する CPU コアを定義。数値の桁数がコア数を示し、個々の数値がプロセスと使用コア番号を示す。CPU コア数 3 で設定。

pid
Nginx デーモンの pid ファイルのパス。

Events モジュール

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

worker_connections
ワーカプロセスが同時に処理できる接続数。今回は 3 つのワーカプロセスを有効にしているため、設定数の 3 倍の接続数を処理することができる。

use epoll
epoll はデフォルトの select より効率がよい。epoll は Linux Kernel 2.6 以上で使用できる。

http モジュール

server_tokens
on なら http レスポンスヘッダとエラーページのフッタに Nginx のバージョンを表示する。

server_name_in_redirect
on ならリダイレクト時 server_name のホスト名でリダイレクトする。off なら http リクエストの Host ヘッダでリダイレクトする。

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

client_max_body_size
http リクエストのサイズ上限。大きなファイルをアップロードするなら調整する。デフォルトは 1MB。

client_body_buffer_size
http リクエストのバッファサイズ。アップロード予定のファイルの値より大きくしておく。

sendfile
on ならファイルの読み込みとレスポンスの送信に sendfile() APIを使う。sendfile() はカーネル内で処理を行うため高速。

tcp_nopush
on なら http レスポンスヘッダをひとつの TCP パケットで送る。この設定を有効にするには sendfile を on にしておく必要がある。

gzip_static
on なら要求ドキュメントを探す時に .gz を最初に探す。

gzip
on なら http レスポンス全体を Gzip で圧縮する。

gzip_http_version
http プロトコルのバージョンに対して Gzip を有効にする。1.0 が無難。

gzip_vary
on なら http レスポンスに Vary: Accept-Encoding ヘッダを追加する。

gzip_comp_level
Gzip 圧縮レベル。1-9 を指定できる。9 が圧縮率最大。

gzip_types
Gzip 圧縮を有効にする MIME タイプ。text/html はデフォルトで有効。

gzip_disable
http リクエストの User-Agent ヘッダに指定した文字列があれば Gzip 圧縮を無効にする。IE1-6 は Gzip 圧縮に対応していないため無効にすることが多い。

proxy_cache_path
キャッシュファイルを格納するディレクトリと、キャッシュの最大サイズ、有効期間などを設定する。

proxy_temp_path
キャッシュの一次ファイルを格納するディレクトリを指定する。

proxy_cache_key
キャッシュファイルのキーとなる文字列。URL(クエリストリング含む) を指定することが多い。PC とモバイルで出力結果が違う場合、キーを分ける必要がある。

proxy_set_header
backend サーバに送信するヘッダを定義し直す。

proxy_connect_timeout
backend サーバへの接続タイムアウト時間。

proxy_send_timeout
backend サーバへの送信タイムアウト時間。

proxy_read_timeout
backend サーバからの読み込みタイムアウト時間。

proxy_hide_header
クライアントに見せない隠し http レスポンスヘッダを追加する。

proxy_cache_use_stale
指定した条件下でキャッシュから応答する。

proxy_cache_lock
on ならキャッシュが有効なとき、複数のリクエストをひとつに束ねて backend サーバに転送する。

proxy_cache_lock_timeout
proxy_cache_lock のタイムアウト。デフォルトは 5s。

upstream
バックエンドサーバを定義する。

単位記号は以下の通り

  • s:秒 m:分 h:時 d:日 w:週 M:月(30日) y:年(365日)
  • k|K:キロバイト m|M:メガバイト 1M=1024K

VirtualHost 設定

VirtualHost 設定は nginx.conf に書くこともできますが、別のファイルにすると管理しやすいです。ここでは、/etc/nginx/conf.d/wordpress.conf で設定します。
ポイントは以下の通り。

  • js, css, 画像はバックエンドに転送しない。
  • .php はキャッシュせずバックエンドへ転送。
  • SSL によるアクセスを許可。
  • SSL によるアクセスはキャッシュせずバックエンドへ転送。
  • SSL 領域はベーシック認証で保護。
  • WordPress はレスポンシブデザインで構築しているので、デバイス別にキャッシュを振り分けない。
  • ログインしていたらキャッシュしない。
  • wp-config.php へのアクセス禁止。

SSL 秘密鍵と自己証明書、.htpasswd は お名前.com VPS にApacheをインストールしてSSL環境も整える で作成したものを使いまわしています。

/etc/nginx/conf.d/wordpress.conf

server {
    listen 80;
    server_name example.com;
    root /var/www/wordpress;
    index index.php;
    charset utf-8;
    access_log  /var/log/nginx/wordpress-front-access.log  main;
    error_log   /var/log/nginx/wordpress-front-error.log warn;
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt { access_log off; log_not_found off; }
    location = /apple-touch-icon.png { access_log off; log_not_found off; }
    location = /apple-touch-icon-precomposed.png { access_log off; log_not_found off; }
    location ~ /\. { deny all; access_log off; log_not_found off; }
    location = /xmlrpc.php { deny all; access_log off; log_not_found off; }
    location = /wp-config.php { deny all; }
    location ~ \.(xml|gz)$ { expires 1d; }
    location ~ \.(js|css|txt)$ { expires 1M; }
    location ~ \.(ico|png|gif|jpg|jpeg)$ { expires 1y; }
    location ~ \.php$ { proxy_pass http://backend; }
    location / {
        set $do_not_cache 0;
        if ($http_cookie ~ "wordpress_logged_in_|comment_author_") {
            set $do_not_cache 1;
        }
        if ($request_method = POST) {
            set $do_not_cache 1;
        }
        proxy_no_cache     $do_not_cache;
        proxy_cache_bypass $do_not_cache;
        proxy_redirect     off;
        proxy_cache        one;
        proxy_cache_key    "$scheme://$host$request_uri";
        proxy_pass         http://backend;
    }
}
server {
    listen 443;
    server_name example.com;
    root /var/www/wordpress;
    index index.php;
    charset utf-8;
    auth_basic            "Please Enter Your Password";
    auth_basic_user_file  "/var/www/.htpasswd";
    access_log  /var/log/nginx/wordpress-ssl-access.log  main;
    error_log   /var/log/nginx/wordpress-ssl-error.log warn;
    ssl                  on;
    ssl_certificate      /etc/pki/tls/certs/wordpress.crt;
    ssl_certificate_key  /etc/pki/tls/private/wordpress.key;
    ssl_session_timeout  5m;
    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;
    location = /favicon.ico { access_log off; log_not_found off; }
    location ~ /\. { deny all; access_log off; log_not_found off; }
    location = /wp-config.php { deny all; }
    location ~ \.php$ {
        expires        off;
        fastcgi_pass   phpfpm;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_param  REMOTE_ADDR      $http_x_real_ip;
        fastcgi_pass_header "X-Accel-Redirect";
        fastcgi_pass_header "X-Accel-Buffering";
        fastcgi_pass_header "X-Accel-Charset";
        fastcgi_pass_header "X-Accel-Expires";
        fastcgi_pass_header "X-Accel-Limit-Rate";
        fastcgi_buffer_size 8k;
        fastcgi_buffers 64 8k;
    }
}
server {
    listen unix:/var/run/nginx-backend.sock;
    server_name  example.com;
    root   /var/www/wordpress;
    access_log  /var/log/nginx/wordpress-backend-access.log  backend;
    error_log   /var/log/nginx/wordpress-backend-error.log warn;
    gzip              off;
    gzip_vary         off;
    location / {
        index  index.php index.html;
        try_files $uri $uri/ /index.php?$args /index.php?q=$uri&$args;
    }
    location ~ \.php$ {
        try_files $uri =404;
        expires        off;
        fastcgi_pass   phpfpm;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_param  REMOTE_ADDR      $http_x_real_ip;
        fastcgi_pass_header "X-Accel-Redirect";
        fastcgi_pass_header "X-Accel-Buffering";
        fastcgi_pass_header "X-Accel-Charset";
        fastcgi_pass_header "X-Accel-Expires";
        fastcgi_pass_header "X-Accel-Limit-Rate";
    }
}

listen
リスニングソケット。IP アドレス、ポート番号、UNIX ドメインソケットを指定できる。

server_name
ホスト名

root
ドキュメントルート

proxy_no_cache
1 ならキャッシュしない。

proxy_cache_bypass
1 ならキャッシュから取得しない

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

proxy_cache
キャッシュゾーンを定義。

proxy_cache_key
キャッシュのキーを定義。出力毎にユニークになるように。

proxy_pass
バックエンドサーバの場所を定義。upstream を設定している。

location のプレフィックスは以下の通り

  • なし: 前方一致(後方にある location の参照も行う)
  • ^~: 前方一致(後方にある正規表現で記述された location の参照を行わない)
  • ~: 正規表現(大文字小文字を区別する)
  • ~*: 正規表現(大文字小文字を区別しない)
  • =: 完全一致

WordPress ファイルの 所有者を nginx に変更

これまでの記事に従って設定している方は、wordpress の所有者が apache になっているはずです。chown コマンドで nginx に変更します。

# chown -R nginx:nginx /var/www/wordpress
# chown nginx:nginx /var/www/wordpress/.htaccess

WordPress の functions.php で expires header を出力

Nginx のデフォルトでは PHP が Expires header を出力しないと結果がキャッシュされない様子。有効期間はリバースプロキシと同じ 1日にしています。Nginx の設定で Expires header なしでもキャッシュするようにできるらしいですが、未確認です。

add_action("template_redirect", "my_cache_control");
function my_cache_control() {
    header("X-Accel-Expires: 86400");
}

WordPress の 404 ページをキャッシュする

WordPress の 404 ページが Cache-Control:no-cache, must-revalidate, max-age=0 ヘッダーをつけるので、そのままだと Nginx がキャッシュしない。

wp-includes/class-wp.php の nocache_headers(); をコメントアウト。

function handle_404() {
    global $wp_query;
    if ( !is_admin() && ( 0 == count( $wp_query->posts ) ) && !is_404() && !is_robots() && !is_search() && !is_home() ) {
        // Don't 404 for these queries if they matched an object.
        if ( ( is_tag() || is_category() || is_tax() || is_author() || is_post_type_archive() ) && $wp_query->get_queried_object() && !is_paged() ) {
            if ( !is_404() )
                status_header( 200 );
            return;
        }
        $wp_query->set_404();
        status_header( 404 );
		//コメントアウト
        //nocache_headers();
    } elseif ( !is_404() ) {
        status_header( 200 );
    }
}

アクセスログを確認する

リバースプロキシが有効になっているかどうか、アクセスログを確認します。リバースプロキシが機能していれば wordpress-backend-access.log への書き込みが減るはずです。

キャッシュ系プラグインの利用状況

「001 Prime Strategy Translate Accelerator」(翻訳ファイルの読み込みをキャッシュ化) のみ使用しています。「W3 Total Cache」 も、「DB Cache Reloaded Fix」も使用していません。理由としては

終わりに

Nginx で WordPress を動作させ、リバースプロキシを有効にする方法を紹介しました。次回はお名前.com のDNSを設定し、VPSに独自ドメインでアクセスするところをやります。

WordPress
お名前.com のDNSを設定し、VPSに独自ドメインでアクセスする

お名前.com VPS メモリ2G プランに Nginx で WordPress を構築するメモ、第 11 回目。前回は ...

続きを見る

参考サイト nginx連載 - インフラエンジニアway

-技術ブログ
-