WordPressのadmin-ajax.phpをNginxでキャッシュする設定

/wp-admin/admin-ajax.phpに対してキャッシュを効かせたくAWSのCloudFrontで最初はキャッシュをさせようと思ったのですが、管理画面のメディアでこのエンドポイントに対してPOSTでリクエストが来ており、CloudFrontでキャッシュの設定を色々試してみたのですがうまく行かずNginxで設定してみました。

設定

/etc/nginx/nginx.conf

fastcgiのキャッシュファイルを置く場所の設定です。場所などの設定は適宜書き換えてください。

fastcgi_temp_path  /dev/shm/fastcgi_proxy_temp 1 1;
fastcgi_cache_path /dev/shm/fastcgi_cache levels=1:2 keys_zone=fastcgi-cache-space:20m max_size=300m inactive=10m;

/etc/nginx/vhost.d/example.conf

キャッシュの状態を確認できるように$upstream_cache_statusという変数を使用してヘッダーに乗せています。

$upstream_cache_statusにはMISS, BYPASS, EXPIRED, STALE, UPDATING, REVALIDATED, HITが入ります。

キャッシュはGET/HEADのみ(fastcgi_cache_methodsのデフォルト値を使用)、fastcgi_cache_keyでクエリストリングまでキャッシュのキーとして使用しています。

また、200のみをキャッシュ対象として10分間のキャッシュにしています。

location ^~ /wp-admin/admin-ajax.php {
    include fastcgi_params;

    fastcgi_cache_key        "$host$request_uri";
    fastcgi_ignore_headers   Cache-Control Expires Set-Cookie;
    fastcgi_pass             php;
    fastcgi_intercept_errors on;
    fastcgi_param            SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_cache            fastcgi-cache-space;
    fastcgi_cache_valid      200 10m;

    add_header X-Cache-Status $upstream_cache_status;
}

このような設定をserverディレクティブに追加しました。全体の設定の主要部分を抜き出したものが↓です。おそらくこれで動くはず

upstream php {
    server unix:/var/run/php-fpm/php-fpm.sock;
}

server {
    listen 80;

    server_name example.com;
    root        /var/www/html/example/current;
    index       index.php;

    access_log  /var/log/nginx/access.example.log ltsv;
    error_log   /var/log/nginx/error.example.log warn;

    client_max_body_size 100M;

    location ^~ /wp-admin/admin-ajax.php {
        include fastcgi_params;
    
        fastcgi_cache_key        "$host$request_uri";
        fastcgi_ignore_headers   Cache-Control Expires Set-Cookie;
        fastcgi_pass             php;
        fastcgi_intercept_errors on;
        fastcgi_param            SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_cache            fastcgi-cache-space;
        fastcgi_cache_valid      200 10m;
    
        add_header X-Cache-Status $upstream_cache_status;
    }

    location ~ \.php$ {
        include                  fastcgi_params;
        fastcgi_pass             php;
        fastcgi_intercept_errors on;
        fastcgi_param            SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }
}

参照