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 もできるし、もうそれでよくね?