WordpressでNginx(FastCGIcache)の設定

ここまでの準備は
[WordPress(PHP7+nginx) for Amazon Linux AMI 2016.09](http://qiita.com/ki6ool/items/8e929a460da3bb7a878a)
[PHP7.4+Nginx for Amazon Linux 2](https://qiita.com/ki6ool/items/6737b963bfd6961084e6)

## nginx.conf

自分用の設定なので適宜変更してください。

```nginx:nginx.conf
http {

    index   index.php index.html index.htm;

    #Fastcgi_cache
    fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=FCKZ:32m inactive=1d max_size=128m;
    fastcgi_cache_use_stale error timeout invalid_header http_500;

    server {
        listen       443 ssl http2;
        listen       [::]:443 ssl http2;
        server_name  localhost;
        root         /var/www/html;
        index        index.php;

        #include /etc/nginx/default.d/*.conf;

        #Fastcgi_cache
        set $do_not_cache 0;
        if ($request_method !~ ^(GET)$) {
                set $do_not_cache 1;
        }
        if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.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;
        }
        set $mobilef '';
        #モバイル判定しない場合は不要
        if ($http_user_agent ~* '(Mobile|Android|Silk|Kindle|BlackBerry|Opera Mini|Opera Mobi)') {
            set $mobilef 'mobile.';
        }
        fastcgi_cache_key "$mobilef$scheme://$host$request_uri";

        #For Wordpress
        location / {
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass  php-fpm;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            include fastcgi_params;

            fastcgi_cache_bypass $do_not_cache;
            fastcgi_no_cache $do_not_cache;
            fastcgi_cache FCKZ;
            fastcgi_cache_valid  200 5m;
            fastcgi_cache_valid  any 10m;
            fastcgi_pass_header X-Accel-Expires;
            fastcgi_ignore_headers Cache-Control Expires;
            add_header f-cache $upstream_cache_status;
        }

        location ~* ^.+.(jpg|jpeg|gif|png|css|js|flv|swf|ico|xml)$ {
            access_log  off;
            log_not_found off;
            expires 30d;
        }

        location ~ /(\.ht|\.user.ini|\.git|\.hg|\.bzr|\.svn) {
            deny  all;
        }

    }
}
```

include /etc/nginx/default.d/*.conf;
でインクルードされてる中にlocationがかぶると優先順位で効かない場合あるので注意。
注意というかコメントアウトでいいと思われ。
Amazon Linux AMI 2016.09以降は

```
fastcgi_pass  php-fpm;
```



モバイル判定のUAはWordpressの *wp_is_mobile()* とほぼ同等にした。

<img width="372" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97451/155a0e38-bdff-521e-9409-e72e8fab91d8.png">

ChromeのNetworkでhttpヘッダーを確認して
f-cache: HIT
になってれば有効になっている


参考
- [Nginxのfastcgi_cacheでWordPressを高速化](http://takayukii.me/post/20160218631)
- [[技術ブログvol.29] NginxのチューニングとFastCGIcacheの設](http://www.denet.ad.jp/technology/2015/05/vol29-nginxfastcgicache.html)
- [Nginx の fastcgi cache を利用して WordPress を高速化する](https://mano.xyz/1619/)
- [CentOSのNginxにFastCGIキャッシュを設定してサイト速度を100倍にする](https://www.rem-system.com/nginx-fastcgi-cache/)
- [Nginxのキャッシュがうまく効いてなかったのを解決しました](https://ansoku.me/2016/11/solve-the-nginx-cache-problem/)


## Nginx Cache Controller

プラグインをインストールする。
[Nginx Cache Controller](https://ja.wordpress.org/plugins/nginx-champuru/)

```php:functions.php
add_filter('nginxchampuru_flush_cache', function ($url) {
    $nginxchampuru = NginxChampuru::get_instance();
    global $wpdb;
    $table = "{$wpdb->prefix}nginxchampuru";
    $query = "select `cache_key` from `{$table}` where `cache_url` = %s";
    $keys = $wpdb->get_col($wpdb->prepare($query, $url));
    $caches = $nginxchampuru->get_cache_file($keys);
    foreach ($caches as $cache) {
        if ( is_file($cache) ) unlink($cache);
    }
    $sql = "delete from `{$table}` where cache_key in ('" . join( "','" , $keys ) . "')";
    $wpdb->query($sql);
}, 10, 1);
/*
add_filter('nginxchampuru_get_reverse_proxy_key', function ($url) {
    $key = $url;
    if ( wp_is_mobile() ) {
        $key = 'mobile.' . $url;
    }
    return md5($key);
}, 10, 1);
*/
add_filter('nginxchampuru_get_cache', function ($key, $url = null) {
    global $nginxchampuru;
    if ( !$url ) {
        $url = $nginxchampuru->get_the_url();
    }
    $http_url = str_replace('https', 'http', $url);
    $keys = [
        $key,
        $nginxchampuru->get_cache_key($http_url),//ELB使ってる場合
        $nginxchampuru->get_cache_key('mobile.'.$url),//モバイル用を追記した場合
        $nginxchampuru->get_cache_key('mobile.'.$http_url)//モバイル用を追記してさらにELB使ってる場合
    ];
    if ( $key !== $nginxchampuru->get_cache_key($url) ) {
        $keys[] = $nginxchampuru->get_cache_key($url);
    }
    return $nginxchampuru->get_cache_file($keys);
}, 10, 2);

```

あとはプラグインの管理画面で設定変更する。


####2022-01-21追記
プラグインからキャッシュファイルが消えないのでいよいよ真面目に調べた。
「nginxchampuru_get_reverse_proxy_key」は意味がないことがわかった。

ELB経由だとfastcgi側は「http://〜」を元にキーが生成されるが、
Wordpress（Plugin）側だと「https://〜」を元にキーが生成されるので
キーが異なって削除されなかった。
ので「nginxchampuru_get_cache」を引っ掛ける。