情報科学屋さんを目指す人のメモ

方法・手順・解説を書き残すブログ。私と同じことを繰り返さずに済むように。

NginxからApacheに変更してNginx Cache Controllerからキャッシュが削除できなくなった原因と対策

Apache (5) Nginx (11) WordPress (76)

リバースプロキシ(Nginx)のキャッシュをNginx Cache ControllerというWordPressプラグインから削除していたのですが、WordPressが動いているサーバをNginxからApacheに変更したところ、動かなくなってしまいました。その原因探しの経過と対策をメモ。

Nginx Cache Controllerの削除方法

Nginx Cache Controllerは、リバースプロキシ(Nginx)が作成したキャッシュファイルを、直接PHPのunlink関数で削除しにかかります。Nginx Cache Controllerの実行はWebサーバ(Apache)がするため、実行ユーザによっては、パーミッションに関する問題(Permission denied)が発生してしまいます。

nginxとapacheのユーザ設定

nginxの実行ユーザは、nginx:wwwで、apacheの実行ユーザは、apache:wwwです。ディレクトリにsetgidを設定して、グループ権限で書き込めるようにして、共存させています。

umaskでは上手くいかない

キャッシュを作るNginxに「umask 0002」を実行させて、キャッシュファイルにグループからの書き込み権限を与える(770にする)事にしました。これと、setgidと組み合わせれば、うまくいくかな、と。

まずは、Apacheでumaskを実行する方法(linux - Setting the umask of the Apache user - Stack Overflow)を参考に、「/etc/sysconfig/nginx」の最終行に「umask 0002」を追加しました。しかし、作成されたキーごとのキャッシュディレクトリがdrwx--S---、キャッシュファイル本体が-rw-------になってしまいました。

「su -c "umask 0002" nginx」もだめ

また、海外のメーリングリストで試して失敗していた人がいた「su -c "umask 0002" nginx」も試してみましたが、そもそも「This account is currently not available.」になってしまいました。これは、nginxがログインユーザじゃないからで、passwdを書き換えるなどすれば、実行自体はできるようですが、やめておきました。

というより、Apacheにはumask 0002の情報はたくさんあるのに、Nginxの場合はほとんどありませんし、対策が紹介されていても、結局成功していないものばかりでした。

やはり実行ユーザを揃える?

というわけで、nginxのキャッシュファイルのファイルパーミッションの変更は結局上手くできませんでした。また、WordPressにも、グループの書き込み権限があっても、所有者と実行ユーザが一致しないとプラグインの削除ができない設定がデフォルトだったりするので、結局NginxとApacheの実行ユーザを揃える方がよいのではないか、となりました。

そこで、「/etc/httpd/conf/httpd.conf」の「User apache」を「User nginx」に、「SuexecUserGroup apache www」を「SuexecUserGroup nginx www」に変更しました(対応するところを直しただけ)。しかし、上手く削除されませんでした。

そもそもキャッシュキーは正しいのか

ここで、そもそもキャッシュキーの設定が正しいのかを調べました。この時点で、スマートフォン用キャッシュを削除する設定方法を紹介した記事の通りに、「proxy_cache_key "$scheme://$proxy_host$uri$is_args$args$mobile"; 」となっていました。ここで、$_SERVER['HTTP_HOST']の値がおかしくなっていたのを修正した事を思い出しました。

そこで、$proxy_hostの値がどうなっているのか調べてみると、やはり「backend」でした。というわけで、どうせわかりきっているのだからと、直接「proxy_cache_key "http://did2memo.net$uri$is_args$args$mobile";」とURLを指定指定してしまう事にしました。すると、見事にキャッシュ削除に成功するようになりました。つまり、今までずっとNginx側もApache側も「http://backend/」で始まるキャッシュキーが生成されていて、ホスト名を正しく認識するように変更した結果、Apache側だけ「http://did2memo.net/」で始まるキャッシュキーが作成されるようになってしまい、Nginx側のキャッシュキー生成との不一致が起こってしまっていたのです

確認のためにUser指定を戻してみると

ここで、そもそもパーミッションが原因ではなかったのではないか、という可能性をチェックするために、一度httpd.confの「User nginx」を「User apache」に戻してみる事にしました。すると、やはり削除が上手くいきません。というわけで、パーミッションの設定(httpd.confでの「User nginx」)もやはり必要だったということがわかりました。

原因は「パーミッション」と「キャッシュキー」の2つだった!

というわけで、原因はパーミッションとキャッシュキーの両方だった、ということがわかりました。どちらも、「Nginx+Nginx」の構成から「Apache+Nginx」に変更した事が直接的な原因となって発生した問題でした。

ちょっと難しかったですが、うまくキャッシュが削除できるようになってめでたしめでたしです。

コメント(0)

新しいコメントを投稿