分かる人にしか分からないタイトルにしてみました。ころすけ(@wg_koro)です。
このブログ(WordPress)はnginxとfastcgiで運用しているんですが、設定を見直していると「あれ?」と思うことが。
Cache Purgeプラグインで403
WordPressにはNginx Proxy Cache Purgeというプラグインを入れています。これはエントリーを投稿/編集/削除した時に、特定のURL(nginxのキャッシュを削除するためのURL。デフォルトは「/purge/エントリーパス」)にHTTPアクセスをしてくれるプラグインです。
アクセスログを調べると、この/purge以下のアドレスにアクセスした時に403が返されています。あれれ?本来は200か404(キャッシュが存在しない時は404)が返るはず。こりゃあかん。
原因
アクセス許可していなかった。
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]
ローカルの127.0.0.1のみアクセス許可していたんですが、ログをよく調べたら、purgeプラグインはサーバー自身のIPアドレスでアクセスしていました。なるほどこれか。
というわけで、サーバー自身のIPを許可するように修正。
location ~ /purge(/.*) {
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]
モバイル用のキャッシュはpurgeされていない
よく調べたら、スマートフォンやケータイ向けのキャッシュが削除されていませんでした。
nginxのconfigはあちこちで説明されているものを流用しています。キャッシュ部分はこんな感じ。
set $mobile ""
if ($http_user_agent ~* ‘(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|WindowsCE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)’) {
set $mobile 1;
}
if ($http_user_agent ~* ‘(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows Phone)’) {
set $mobile 2;
}
:(略)
proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
[/shell]
User Agentで変数$mobileを振り分ける。この変数をキャッシュキーに組み込み、PC、ケータイ、スマートフォンで異なるキャッシュが生成されるようにしてあります。
Purge部分も、他で説明されているものをそのまま使用。
location ~ /purge(/.*) {
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]
あれ、これだと変数$mobileは「PC」になるからPC用キャッシュは削除できるけど、ケータイ、スマートフォン用のキャッシュは削除できないんじゃないか?。
確認してみると、PC用キャッシュはクリアされていましたが他のデバイス向けキャッシュは残ったままでした。やっぱり。
結局、こうしてみた
1.各デバイス用のPurge URLを用意する
location ~ /purge(/.*) {
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
# スマートフォンやケータイ用のPurge URLを用意する
location ~ /pg_s(/.*) {
set $mobile 2;
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx;
deny all;
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
location ~ /pg_f(/.*) {
set $mobile 1;
allow 127.0.0.1;
allow xxx.xxx.xxx.xxx.
deny all;
proxy_cache_purge czone "$scheme://$host$1$is_args$args$mobile";
}
[/shell]
/purge 以外に、下記2つのURLを用意しました。
- /pg_s/xxx スマートフォン用キャッシュ削除
- /pg_f/xxx ケータイ用キャッシュ削除
2.Nginx Proxy Cache Purgeを改造
purgeプラグインが動く時、/purgeだけでなく /purge, /pg_s, /pg_f 3つのURLにアクセスするようにnginx-proxy-cache-purge.phpを改造します。
改造したらエントリーを更新して、アクセスログを確認してみる。
うん、ちゃんと3つのURLにアクセスされていますね。※pg_fはケータイ用のキャッシュを作っていないので404でOK。
念のため、configにadd_header X-Cache $upstream_cache_status;をセットしてキャッシュステータスも確認してみる。
ステータスがMISS(キャッシュが使われていない状態)になっているのでOK。これでエントリー編集・削除時に全デバイスのキャッシュが削除されるようになりました。満足!
今回作ったパッチファイルはコチラ (Gist)