※弊社記事はたぶんにPRが含まれますので
話半分で受け取ってください。

NginxでWordPressを動かす設定のメモ

 Nginx で WordPress を動かす設定のメモ。fastcgi cache を利用しています。

 Nginx のキャッシュ機能は proxy cache と fastcgi cache があります。
 proxy cache は web サーバの前段に proxy サーバを置いて、そこにキャッシュを置く方法。fastcgi cache は FastCGI(WordPress の場合は PHP)のレスポンスをキャッシュする方法。

 前は proxy cache 構成にしていたのですが、別に複数サーバとかクラウドとか使ってるわけでもないので、今は proxy cache よりも構成が単純な fastcgi cache で運用しています。

設定

 追加・編集するファイルは以下の通り。それ以外はデフォルトです。(たぶん。)

/etc/nginx/
├ conf.d
│ ├ default.conf
│ └ fastcgi_cache.conf
├ sites-available
│ └ icoro.com
├ sites-enable
│ └ icoro.com
└ snippets
│ ├ jetpack-ip.conf
│ ├ limit.conf
│ ├ php_wp.conf
│ └ restrict.conf
└ nginx.conf

 伝統の秘伝ソースに、さらにあちこちググってつぎはぎをほどこしたソースなので、最適な設定になってる保証はありません。一応、この設定で動いてはいる。

nginx.conf

 nginx.conf はGzip設定をコメントアウトするだけで基本デフォルトのまま。てか、この部分も conf.d/default.conf に吐き出してしまえば nginx のアップデート時にいじらなくてよくなるのでは。

##
# Gzip Settings
##

gzip on;

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

conf.d/default.conf

 主な設定内容はファイルキャッシュ、PHP、接続制限の3つ。
 PHP で UNIX domain socket を使ってると PHP のバージョンが上がったときにこの設定も変更しなきゃでちょっとあれ。なんかすればなんかなるんだろうけど、できるだけデフォルト運用が身上なのでなにもしてません。

##
# Custom Configs
##

index                 index.php index.html index.htm;
client_max_body_size  8M;

# file cache
open_file_cache          max=100000 inactive=20s;
open_file_cache_valid    30s;
open_file_cache_min_uses 2;
open_file_cache_errors   on;

# php
upstream php {
    # UNIX domain socket
    server unix:/run/php/php8.2-fpm.sock;

    # TCP
    #server 127.0.0.1:9000;
}

# limit setting

# 同時接続数制限を行う際のメモリ領域を10MB確保
limit_conn_zone $binary_remote_addr zone=LIMIT_CONN_ZONE:10m;

# 50リクエスト/sを超えるペースだと503を返す
limit_req_zone $binary_remote_addr  zone=LIMIT_REQ_ZONE:10m rate=50r/s;

conf.d/fastcgi_cache.conf

 主に fastcgi の cache についての設定。

##
# Fastcgi Cache Configs
##

proxy_buffering          on;
fastcgi_buffers          16 16k; #up to 4k + 128 * 4k
fastcgi_buffer_size      32k;
fastcgi_temp_path        /var/tmp/nginx;

fastcgi_connect_timeout  60;
fastcgi_read_timeout     120;
fastcgi_send_timeout     60;

# fastcgi cache
fastcgi_cache_valid      200 2h;
fastcgi_cache_valid      302 2h;
fastcgi_cache_valid      301 4h;
fastcgi_cache_valid      any 1m;

fastcgi_cache_path  /var/cache/nginx levels=1:2 keys_zone=CZONE:4m max_size=500m inactive=60m;
fastcgi_cache_key   "$scheme$request_method$host$request_uri";

# cache 404 or other
fastcgi_ignore_headers  Cache-Control Expires Set-Cookie;

# return old cache if PHP crashes
fastcgi_cache_use_stale  error timeout invalid_header http_500;

sites-available/icoro.com

 ドメイン別の設定。icoro.com の部分は自分の設定するドメインに合わせて変更してください。

#
# 80/443 default setting
#

# redirect setting

# http を https に転送するときはこの部分のコメントをはずす。
# server {
#     listen       80;
#     server_name  icoro.com;
#     return       301 https://icoro.com$request_uri;
# }

server {
    # use http & https
   listen       80 default_server;
   listen       443 ssl http2;

    # https only
#    listen       443 ssl http2 default_server;

    server_name  icoro.com;
    root         /var/www/icoro.com;

    # ssl setting
    ssl_certificate     /etc/letsencrypt/live/icoro.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/icoro.com/privkey.pem; 

    # log
	# ログを分けたいときはここで設定する
#    access_log /var/log/nginx/icoro.access.log;
#    error_log /var/log/nginx/icoro.error.log;

    # restrictions
    include snippets/restrict.conf;

    # for letsencrypt webroot
    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
    }

    location / {
        # limit zone setting
        include snippets/limit.conf;

        # This is attempted to match last if.
        try_files $uri $uri/ /index.php?$args;
    }

    # Add trailing slash to */wp-admin requests.
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

    # XML-RPC
    location = /xmlrpc.php {
        include snippets/jetpack-ip.conf;
    }

    # pass the PHP scripts to FastCGI
    location ~ [^/]\.php(/|$) {
        include snippets/php_wp.conf;
    }

#    location ~ /purge(/.*) {
#        allow 127.0.0.1;
#        allow 219.94.233.156;
#        deny all;
#        proxy_cache_purge CZONE "$scheme$request_method$host$request_uri";
#    }

}

 snippets 下のファイルはバーチャルドメインで複数の WordPress を運用するような場合に設定を使い回したり、設定変更しやすくするためのものです。1サーバ 1 WordPress で運用する場合は sites-available/icoro.com の中に直書きしたほうが管理がラクかも。

sites-enable/icoro.com

 sites-available/icoro.com のシンボリックリンクです。シンボリックリンクは以下のコマンドで作成できます。

$ ln -s /etc/nginx/sites-available/icoro.com /etc/nginx/sites-enable/

snippets/jetpack-ip.conf

 xmlrpc.php にアクセスできるIPを設定。Jetpack を利用するのに wordpress.com 関係の IP からだけ xmlrpc.php にアクセスできるようにします。

#
# Jetpack ip list
#

# https://jetpack.com/support/hosting-faq/
# https://jetpack.com/support/how-to-add-jetpack-ips-allowlist/

allow 122.248.245.244/32;
allow 54.217.201.243/32;
allow 54.232.116.4/32;
allow 192.0.80.0/20;
allow 192.0.96.0/20;
allow 192.0.112.0/20;
allow 195.234.108.0/22;
deny all;

snippets/limit.conf

 DDoSなどの過剰なアクセスに対する制限を設定。

#
# limit configuration file.
#

# 1つのIPからの同時接続数が100を超えると503が返る
limit_conn LIMIT_CONN_ZONE 100;

# 50request/secを超えた場合、100リクエストを超えるまで待ってから503を返す
limit_req zone=LIMIT_REQ_ZONE burst=100;

snippets/php_wp.conf

 WordPress 用の PHP の設定。

#php setting for wordpress

# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info  ^(.+?\.php)(/.*)$;

# Check that the PHP script exists before passing it
#try_files  $fastcgi_script_name = 404;
if (!-f $document_root$fastcgi_script_name) {
    return 404;
}

fastcgi_pass   php; # from conf.d/default.conf
fastcgi_index  index.php;
include        fastcgi.conf;

# Cache Setting
# https://ja.wordpress.org/support/article/nginx/

set $do_not_cache 0;

if ($request_method != GET) {
    set $do_not_cache 1;
}
if ($query_string != "") {
    set $do_not_cache 1;
}
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 $do_not_cache 1;
}
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $do_not_cache 1;
}

fastcgi_no_cache     $do_not_cache;
fastcgi_cache_bypass $do_not_cache;
fastcgi_cache        CZONE; # from conf.d/fastcgi_cache.conf

fastcgi_cache_key    "$scheme://$host$request_uri$is_args$args";
fastcgi_cache_valid  200 301 302 60m;
fastcgi_cache_valid  404 5m;
add_header X-F-Cache $upstream_cache_status;

snippets/restrict.conf

 静的ファイルに対するキャッシュやアクセスログの有無に関する設定。

#
# Global restrictions configuration file.
#

# favicon
location = /favicon.ico {
    log_not_found off;
    access_log    off;
}

# robots.txt
location = /robots.txt {
    allow         all;
    log_not_found off;
    access_log    off;
}

#Directives to send expires headers and turn off 404 error logging.
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    access_log    off;
    log_not_found off;
    expires       30d;
}


# Deny all attempts to access hidden files 
# such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
    deny          all;
    access_log    off;
    log_not_found off;
}

 最近はレンサバも WordPress が速いことをウリにしてたりするのでわざわざ VPS 立てたりしなくてもよくなってるっぽい? VPS 使う場合も kusanagi を使うほうが速くて簡単だし、Cloudflare 通せばDDoS 対策も WAF もできるし、もうそれでよくね?

nginx実践ガイド impress top gearシリーズ

  • メーカー:インプレス
  • カテゴリ:Kindle版
  • 発売日:2017/02/16

関連する記事