はじめに
「FTPでファイルをアップしたのに、本番サイトだけ古い表示のまま」
「直したはずの内容が、リロードするとまた元に戻る」
WordPress サイトを ConoHa WING で運用していると、こんな現象に出くわすことがあります。
結論を先に言うと、犯人はサーバーの nginx ページキャッシュであることが非常に多いです。この記事では、ファイルは最新なのに古い内容が表示される原因の切り分け方と対処法を、実際にハマった事例をもとに解説します。
症状:ファイルは新しいのに、表示は古い
あるとき、テンプレート(PHP)・CSS・画像を更新して本番にアップしたのに、ブラウザでは古い内容が表示され続けるという相談を受けました。
最初に疑うのは「アップロード先を間違えた」「ファイルが古い」ですが、調べてみると ローカル・ステージング・本番のファイルはすべてバイト単位で一致しており、タイムスタンプも最新でした。
つまり、ファイルは正しく更新されている。にもかかわらず、表示は古い。しかも厄介なことに、
- リロードのたびに新旧が入れ替わって見える
- 時間が経つと直る(こともある)
という不安定な挙動でした。この「新旧が入れ替わる」「時間で直る」という症状こそ、ページキャッシュ特有のサインです。
なぜ起きるのか:nginx がHTMLを丸ごとキャッシュしている
ConoHa WING には「コンテンツキャッシュ」という高速化機能があり、これが nginx 層で 生成済みの HTML ページを丸ごとキャッシュします。
ユーザー
↓ リクエスト
nginx(ページキャッシュ) ← ここで完成済みHTMLを返す
↓ キャッシュが無いときだけ
PHP(WordPress) → DB → HTML生成
ポイントは、ファイルを更新してもキャッシュは自動で失効しないという点です。
PHP テンプレートや CSS を新しくしても、nginx は前回生成したときの古い HTML を握りっぱなしになります。キャッシュの有効期限(TTL)が切れるか、明示的にクリアするまで、ユーザーには古いページが配信され続けます。
「リロードで新旧が入れ替わる」のは、キャッシュの当たり外れ(HIT / MISS)が混在しているためです。
切り分け:X-Nginx-Cache ヘッダで一発で分かる
推測で消し込む前に、レスポンスヘッダを見れば確定診断できます。ConoHa WING は X-Nginx-Cache というヘッダでキャッシュの状態を返します。
curl -I(ヘッダのみ取得)で確認します。
# 通常アクセス
curl -skI 'https://example.com/' | grep -i x-nginx-cache
# → X-Nginx-Cache: HIT ← キャッシュ済みの古いHTMLを配信している
HIT が返ってきたら、そのページはキャッシュから配信されています。
次に、クエリ文字列を付けてキャッシュを回避してみます。クエリが変わるとキャッシュのキーが変わるため、PHP から新鮮に再生成されます。
# キャッシュ回避(毎回違うクエリを付ける)
curl -skI "https://example.com/?v=$(date +%s)" | grep -i x-nginx-cache
# → X-Nginx-Cache: MISS ← PHPから新鮮に生成された
| 状態 | 意味 |
|---|---|
HIT |
キャッシュ済みHTMLを配信(古い可能性あり) |
MISS |
キャッシュに無く、PHPから新規生成した |
EXPIRED |
キャッシュが期限切れで再生成された |
?v=... 付き(MISS)で最新が見え、通常アクセス(HIT)で古いものが見えるなら、原因はページキャッシュで確定です。これで「ファイルが原因ではない」と切り分けられます。
対処法
1. ConoHa の管理画面でキャッシュをクリアする
このキャッシュは nginx がサーバーレベルで管理しているため、SSH でファイルを触っても、FTP で再アップしても消えません。管理画面から消すのが確実です。
ConoHa WING 管理画面
→ サイト管理
→ サイト設定
→ 高速化
→ コンテンツキャッシュ → クリア
2. 開発・編集中はコンテンツキャッシュをOFFにする
頻繁に修正と確認を繰り返すフェーズでは、キャッシュが有効だと「直したのに古い」で何度も混乱します。テスト環境や制作中のサイトは、同じ画面から コンテンツキャッシュを OFF にしておくのが安全です。本番公開・運用フェーズに入ってから ON に戻します。
3. その場で最新を確認したいとき
エンドユーザーに案内する前の自己確認なら、URL にクエリを付けるのが手軽です。
https://example.com/?v=123
加えて、ブラウザ側にもキャッシュが残るので Ctrl + F5(スーパーリロード)も併用しましょう。
ハマりどころ(おまけ)
サーバー内部から curl で本文を取ると空が返ることがある
切り分けのためにサーバーへ SSH して curl https://... で本文を取ろうとすると、空のレスポンスが返ることがあります。SNI / 証明書まわりの都合です。
ヘッダだけ見れば十分なので -I を使うか、ループバックに解決して -k(証明書検証スキップ)で叩くと確認できます。
# ヘッダだけ見る(これで十分)
curl -skI 'https://example.com/'
# どうしても本文が必要なら
curl -skI 'https://example.com/' --resolve example.com:443:127.0.0.1
キャッシュは「ブラウザ」「nginx」の二段がある
「古い表示」の原因は1か所とは限りません。X-Nginx-Cache: MISS でも古く見えるなら、今度は ブラウザキャッシュが残っているケースです。サーバー側(nginx)とクライアント側(ブラウザ)の両方を切り分けると、迷子になりません。
| 層 | 確認方法 | クリア方法 |
|---|---|---|
| nginx ページキャッシュ |
X-Nginx-Cache ヘッダ |
管理画面でクリア / OFF |
| ブラウザキャッシュ | 別ブラウザ・シークレットウィンドウで再現するか |
Ctrl + F5 / 履歴削除 |
まとめ
| やること | 理由 |
|---|---|
| ファイルの中身・タイムスタンプを3環境で照合 | 「ファイルが古い」のか「表示だけ古い」のか切り分ける |
X-Nginx-Cache ヘッダを見る |
HIT / MISS でページキャッシュが原因か確定する |
?v=時刻 でアクセスしてみる |
キャッシュを回避して最新の生成結果を確認する |
| 管理画面でコンテンツキャッシュをクリア / OFF | 根本対処。SSHやFTPでは消せない |
「更新したのに反映されない」の多くは、ファイルではなくキャッシュ層が原因です。ConoHa WING を使っているなら、まず X-Nginx-Cache を疑う。これを知っているだけで、原因不明の数十分が数分に縮みます。