お名前.com VPS メモリ2G プランに Nginx で WordPress を構築するメモ、第10回目。前回は、Nginx と PHP-FPM をインストールするところまでやりました。
-
お名前.com VPS にNginxとPHP-FPMをインストール
お名前.com VPS メモリ2G プランに Nginx で WordPress を構築するメモ、第9回目。前回はさくら ...
続きを見る
今回は、Nginx で WordPress を動作させ、リバースプロキシを有効にします。設定の意味も出来る限り調べ、まとめました。
目次
- Nginx 基本設定
- VirtualHost 設定
- WordPress ファイルの 所有者を nginx に変更
- WordPress の functions.php で expires header を出力
- WordPress の 404 ページをキャッシュする
- アクセスログを確認する
- キャッシュ系プラグインの利用状況
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」も使用していません。理由としては
- W3 Total Cache は Nginx のリバースプロキシが同等の機能を提供しているので不要。
- DB Cache Reloaded Fix は MySQL のクエリキャッシュのヒット率が 80% を超えているので不要。MySQL の設定は お名前.com VPS にMySQLをインストールしWordPress用にチューニング にまとめてあります。
終わりに
Nginx で WordPress を動作させ、リバースプロキシを有効にする方法を紹介しました。次回はお名前.com のDNSを設定し、VPSに独自ドメインでアクセスするところをやります。
-
お名前.com のDNSを設定し、VPSに独自ドメインでアクセスする
お名前.com VPS メモリ2G プランに Nginx で WordPress を構築するメモ、第 11 回目。前回は ...
続きを見る