Super Page Cache for Cloudflare (WordPress Plugin)

Super Page Cache プラグインを利用して WordPress コンテンツを Cloudflare にキャッシュする

Cloudflare を利用した WordPress キャッシュのアプローチ2選

1. Cloudflare WordPress Plugin

2022/12/15時点サービス情報

Cloudflare WordPress Plugin | WordPress Optimization | Cloudflare

  • Automatic Platform Optimization (APO) と呼ばれるサービス
  • APO 特化の場合は 月間 5 ドルのサービス
    • 明示的な表現を見つけられていないが管理画面でのUI操作的には DNS ゾーンごとの契約になる想定
  • 有料プラン (Proプラン以上) を利用していれば、APOの利用権限はバンドルされている

特徴

  • 大きな意味では一般的な CDN と同じアーキテクチャだが、内部的にはキャッシュの世界伝搬の方法が異なる点で、有料プランの利点がある。
  • 具体的には、Workers KV により Key-Value Store のデータが世界伝搬される。つまり、 CDN の Edge が ORIGIN にアクセスする回数をへらすことができる
    • よって、WordPress 本体の負荷が減るほか、ユーザーが低レイテンシーに HIT してしまう可能性を低減することができる
    • How KV works · Cloudflare Workers docs
  • 公式である特徴として、キャッシュデータの Purge の伝搬も早い

2. 3rd-party 無料プラグインを利用する

Super Page Cache for Cloudflare – WordPress plugin | WordPress.org

  • Cloudflare 無料枠の機能でキャッシュする
  • 動作させるために Cloudflare Rules を1個消費する
    • 無料枠では3個しか利用できないため、使いたい場面を見極める必要がある
    • Rules は DNS Zone ごとのはずなので、WordPress マルチサイトでサブドメイン型で作っている場合は適用範囲を広くできる
  • WordPress へログインしている時のみの情報(メニューバー等)をキャッシュしない実装がされている
    • swcfpc=1 パラメタにて、Cache Buster という意味のパラメタが付与される。付与されているページはキャッシュされない
    • Cache Buster は、 wp-config.php に設定する変数 SWCFPC_CACHE_BUSTER で変更することもできる
  • 設定に必要な API Token の権限は、プラグインインストール後の設定画面に説明がある

参考

  • Cache Buster でどのように Cloudflare へのキャッシュを回避しているのか
    • libs/cache_controller.class.php にて is_url_to_bypass() が定義されている
if( isset($_GET[$this->cache_buster]) ...
    return true;
}

詳細メモ: Super Page Cache for Cloudflare の設定

前提:PHP-FPM with Nginx で WordPress を動かしている時の構成

今回の環境は、 Kubernetes 上でのコンテナ構成かつマルチインスタンス構成(マルチサイトではなく、コンテナを複数起動するスタイル)であるため、マルチインスタンス間の同期検討など面倒くさいこともしている。

一般的な Web サーバーへ 通常のお作法で WordPress をセットアップしている場合は、考えることはもっとシンプルに済む。

Super Page Cache for Cloudflare プラグインの共通的な理解

  • プラグインを有効にすると、キャッシュのようなディレクトリが生成される(plugins 配下ではなく、 wp-contnet 直下)
  • 中身
    • PHPファイルは <?php // Silence is golden
    • debug.log は エラー発生時のログ
    • nginx.conf は4行ほど(wp-adminから参照できる)

最初は随時動的生成されるかと思ったが、そこまで変化はないように見える(要確認)

/wp-content/wp-cloudflare-super-page-cache/
/wp-content/wp-cloudflare-super-page-cache/example.com/debug.log
/wp-content/wp-cloudflare-super-page-cache/example.com/nginx.conf
/wp-content/wp-cloudflare-super-page-cache/example.com/purge_cache_queue/index.php

Nginx module: headers-more-nginx

more_clear_headers を利用するため

Nginx 標準では組み込まれておらず、追加でセットアップする必要がある

実例として Nginx 組み込みの Server ヘッダを削除したいケースに使うなど説明がある

openresty/headers-more-nginx-module: Set, add, and clear arbitrary output headers in NGINX http servers

Cloudflare のキャッシュがなかなか適用されない問題

  • cf-cache-status: DYNAMIC が出てしまう
  • cf-cache-status: HIT を目指す必要がある

先に理解しておくべき

用意する方法

きっかけ: Nginx は alpine 版のものを利用。apk add nginx-plus-module-headers-more でインストールできたのだが、 more_clear_headers が効かない。apk の package はバイナリが違うから自身でビルドして解決した旨の言及があったので、自身でビルドして動作成功している。(ただ、apk の package でインストールしたものが使えないのは、たぶん勘違い。)

nginx.confload_module をし忘れていないか最初に確認しておくこと。

load_module modules/ngx_http_headers_more_filter_module.so;

Nginx 利用ケースでの設定ノウハウ(プラグインのフォーラム)

How to overwrite the cache-control header on Nginx? | WordPress.org

Best Max Age on The Server Side! | WordPress.org

WP Cloudflare Super Page Cache – Nginx Settings | WordPress.org

CF-Cache-Status: EXPIRED | WordPress.org

GKEコンテナインスタンス間でのデータ共有

  • GKE (GCP) は ReadWriteMane がディスクが標準ではない。
    • やりたければ NAS を構築する必要があるが、管理対象物を増やしたくないので構築したくない
  • Filestore サービスを利用すれば共有ストレージになるが、最低 1TB からの利用(22年12月現在)かつ当然プロビジョニング分の金がかかるので避けたい
  • Cloud Storage をディスクとして利用する gcsfuse のアプローチがある

GoogleCloudPlatform/gcsfuse: A user-space file system for interacting with Google Cloud Storage

サブディレクトリ docs 配下にもドキュメントがある。特に Mounting 関連はいかを参照

https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/docs/mounting.md

マウント時のオプションはマニュアル参照 (↓は Debian - bullseye のもの)

mount.fuse(8) — fuse — Debian bullseye — Debian Manpages

オプションは多数あるが、なかでも以下のオプションの存在を抑えておくと試行錯誤しやすい。

  • default_permissions
    • By default FUSE doesn’t check file access permissions, the filesystem is free to implement it’s access policy or leave it to the underlying file access mechanism (e.g. in case of network filesystems). This option enables permission checking, restricting access based on file mode. This is option is usually useful together with the allow_other mount option.
  • allow_other
    • This option overrides the security measure restricting file access to the user mounting the filesystem. So all users (including root) can access the files. This option is by default only allowed to root, but this restriction can be removed with a configuration option described in the previous section.
  • allow_root
    • This option is similar to allow_other but file access is limited to the user mounting the filesystem and root. This option and allow_other are mutually exclusive.
  • uid=N
    • Override the st_uid field set by the filesystem (N is numeric).
  • gid=N
    • Override the st_gid field set by the filesystem (N is numeric).

Kubernets へのマウント時 ( containers の各コンテナ設定の直下に記載 )

  • Kubernetes 管理外の手段でマウントすることになるので volumes の定義はない
  • Pod 起動時や終了時のタイミングでマウント操作をするコマンドを実行する
  • securityContext.capabilities.add: ["SYS_ADMIN"] がないとマウントできないSYS_ADMIN については以下の記事参考に。
securityContext:
  privileged: true
  capabilities:
    add:
      - SYS_ADMIN
lifecycle:
  postStart:
    exec:
      # uid: 101 は Nginx コンテナの nginx ユーザー
      command:
        - "gcsfuse"
        - "--uid"
        - "101"
        - "your-gcs-bucket-name"
        - "/var/www/html/wp-content/wp-cloudflare-super-page-cache"
  preStop:
    exec:
      command:
        - "fusermount"
        - "-u"
        - "/var/www/html/wp-content/wp-cloudflare-super-page-cache"