nginxでphpファイルがダウンロードされるときはブラウザキャッシュもチェック
テスト環境ではWebサーバーにnginxを使っているのですが、最近ちょっとSQLiteとMySQLのパフォーマンス比較をしたくなりました。より正確に言うとテスト自体は完了しているのですが、どうせならnginx、mariadb、PHPをそれぞれ最新版にして再テストしよう、と思ったのが運の尽き。トラブって半日つぶしてしまい、それで終わるのも悔しいのでせっかくだからブログのネタにして埋葬しよう、というわけです。
件名のとおり、結論から言うとブラウザキャッシュをクリアするだけで解決したという恥ずかしい話なのですが、案外ハマる人もいるんじゃないかなぁとも思うんですよね~。
nginxのアップデートは実行ファイルの上書きだけで済む
Windows環境での話です。
Webのテスト環境なのにWindowsかよー、という方もいらっしゃるとは思いますが、それ用にCentOS用意するのも面倒だし、UI操作できるの楽だし、なんなら非力なノートパソコンでもテストサーバーと開発環境一式持ち運べるのが気に入っています。仮想PCだとちょっぴり重いしね。
LiteSpeedのWindows版があればそっちを使いたいのですが、残念ながら存在しないのでWindowsのWebサーバーとしてはnginxがワリと一般的じゃないかな、とも思います。
以前の記事で書いたとおり、nginxのインストールは至って簡単。ZIPファイルダウンロードして解凍するだけ。あとはnginx.exeを実行。バックグラウンド動作させたければstartコマンドでnginx.exeを動かしてやれば良いだけです。
https://blog.ver001.com/windows_nginx_install/うちでは長いことnginx 1.18.0を使っていましたが、最近チェックしたら、nginx 1.21.6が出ていたんですね。
https://nginx.org/en/download.htmlリリース日付は先月の1月25日。おー、ほんとに最近だー、と思ったのですが、リリース履歴を見てみると月に1回くらいアップデートしてるみたい。オープンソースはアップデート頻度がすごいねぇ。
ともあれ、さっそくnginx 1.21.6のZIPファイルをダウンロードし、解凍しますが、ここでちょっと魔が差しました。
nginxの本体はnginx.exeだけなので、古い環境にその実行ファイルだけを上書きすればアップデート完了なはずです。実際、過去に何度かそれでアップデートしていますし特に問題が起こったこともありません。
でも、今回はけっこう日が空いたし、せっかくだから、というよくわからない理由で、古いディレクトリを削除し、新しいnginx 1.21.6用のディレクトリを作って起動することにしました。
もちろんそのままではPHPが動かないので、バックアップ済のnginx.confから必要項目を抜き出してコピペです。これでクリーンな環境ができあがったことだろう、とブラウザで開いてみたのですが…
トップページだけ、PHPが実行されずダウンロードされてしまう
http://127.0.0.1/ と入力してローカルのWebサイトを開こうとしたところ、ダウンロード画面になってしまいました。
ん?この現象、なんか見慣れてるぞ。PHPファイルを開こうとしてダウンロード画面になってしまうのはApacheの時代から定番でPHPの設定がちゃんとされていないのが原因です。
さっそくnginx.confを開いてみましたが、ちゃんとfastcgiの設定が書かれて………
location ~ \.php$ {
include fastcgi_params;
}
………………ふぁ!?
あ、そうだそうだ。バーチャルホストを使っているのですが、全サイトにfastcgiの設定をコピペするのが面倒なので、include構文でfastcgi_paramsファイルを読み込むようにしていたのでした。
https://blog.ver001.com/nginx_php_virtualhost/fastcgi_paramsファイルは拡張子が付いていませんが、中身はただのテキストファイルでこんなふうに書かれていたりします。
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
この最後の2行だけ自分で追加していたのですが、古いバージョンからこの設定を持ってくるのを忘れていました。
というわけで、以前使っていたfastcgi_paramsをnginx 1.21.6のconfディレクトリにコピーして再起動。
これでちゃんと開けるはず…………………………………
……………が、またindex.phpファイルがダウンロードされちゃう。
なんでぇ???
nginxのプロセスが残っていた? タスクマネージャーを確認するも、そんなことはない。ちゃんと再起動はされています。
http://127.0.0.1/test.html などとして静的なHTMLファイルを開いてみるとこちらは問題なく表示されます。
どうせダウンロード画面が開くだろうと思いつつ、http://127.0.0.1/index.php を開いてみたら全く問題なく表示されました。PHPスクリプトも正常動作しているのです。
えええ???
◎http://127.0.0.1/test.html
◎http://127.0.0.1/index.php
×http://127.0.0.1/
つまり、index設定がおかしいってこと? そう思ってnginx.confとにらめっこしますが、
index index.php index.html
の記述はあります。
ここからの試行錯誤がほんっと~~~に長かった。何度も何度もnginx.confやfastcgi_paramsを見直したり書き直したりしてもダメ。1.18.0で使っていたconfディレクトリを丸ごと持ってきてもダメ。nginxのstableバージョン1.20.2を持ってきてもダメ。nginxのプロセスも確認したし、何ならPC自体再起動もしてみましたが、効果はなし。
こりゃどうしようもないな、とバックアップしていた nginx 1.18.0 に戻してみたところ…………………… http://127.0.0.1/ は開けないまま。
えええ??? これは本格的にマズいか、と落ち込みかけたとき、ふと別のPCから接続したらどうなのかな、とWebページを開いてみたところ、何の問題もなく http://[コンピューター名]/ で開けたのです。PHPも正常動作。
ブラウザのキャッシュの問題だった
ここまできて、よーやくブラウザの問題だと気が付きました。
上はEdge Chromiumの設定画面ですが、「閲覧データをクリア」画面から「キャッシュされた画像とファイル」だけを選びクリアしてみたところ、まったく問題なくhttp://127.0.0.1/が開けるようになりました。
Edge固有の問題なのか、Chromeでも同じ現象が発生するのか、気になったので試してみました。
- わざとPHP設定が間違った状態のnginxを用意する
- Chromeでhttp://127.0.0.1/を開く → ダウンロード画面が出る
- PHP設定を正常に戻してnginxを再起動する
- Chromeでhttp://127.0.0.1/を開く → やっぱりダウンロード画面が出る
- Chromeでキャッシュをクリアしてからhttp://127.0.0.1/を開く → 正常表示
ということで、EdgeだろうがChromeだろうが、一度PHPのダウンロード画面が出るとその時点でヘッダー情報をキャッシュするためか、ダウンロードすべきファイルとして認識するようですね。
まとめ
- 軽い気持ちでnginxをアップデートしたらPHPの設定を間違えてしまった
- PHPの設定を正常に戻しても一度ダウンロードファイルと認識したブラウザではキャッシュが消えるまで正常に表示できない
詳しい方からしたら当たり前の話かも知れず、わざわざ記事にするのも恥ずかしい限りですが、万が一同じように悩む方がいるといけないので、ブログ記事にしておきました。
はぁー、これでやっとパフォーマンステストが出来る!