Apache キャッシュポリシーの設定
Apache オリジンサーバーで mod_expires または mod_headers を設定して Cache-Control および Expires レスポンスヘッダーを設定し、Alibaba Cloud CDN のエッジノードとブラウザーが静的コンテンツを適切な Time to Live (TTL) でキャッシュするようにします。
モジュールの選択
Apache は、キャッシュヘッダーを制御するために 2 つのモジュールを提供しています。要件に応じて選択してください。
|
モジュール |
利点 |
欠点 |
使用シナリオ |
|
|
シンプルな構文です。MIME タイプごとに |
|
|
|
|
|
構文が若干複雑です。 |
きめ細かいキャッシュポリシーが必要な本番環境。 |
前提条件
開始する前に、必要な Apache モジュールが有効になっていることを確認します。
どのモジュールが読み込まれているかを確認します。
apachectl -M | grep -E "expires|headers"
出力には expires_module と headers_module が含まれるはずです。どちらかが欠けている場合は、有効にします。
Debian / Ubuntu:
sudo a2enmod headers expires
sudo systemctl restart apache2
CentOS / RHEL / Alibaba Cloud Linux:
モジュールは通常、デフォルトでコンパイルされています。モジュールが欠けている場合は、/etc/httpd/conf.modules.d/ を確認し、対応する LoadModule 行がコメントアウトされていないことを確認してから、Apache を再起動します。
sudo systemctl restart httpd
設定は、/etc/httpd/conf.d/ (CentOS/RHEL) または /etc/apache2/conf-available/ (Debian/Ubuntu) 配下の専用ファイル (例:cache.conf) に配置してください。.htaccess ファイルは避けてください。Apache はリクエストごとに .htaccess を解析するため、不要なオーバーヘッドが発生し、パフォーマンス向上の妨げとなります。
設定例
すべての例では <IfModule> ガードを使用しているため、モジュールが存在しなくても Apache はエラーなしで起動します。お使いのコンテンツタイプに合わせて ExpiresByType 行を置き換えるか、拡張してください。
コンテンツタイプ別のキャッシュTTLの設定
単純な max-age ルールには mod_expires を使用し、完全な Cache-Control 制御が必要な場合は mod_headers を使用します。
mod_expires
<IfModule mod_expires.c>
ExpiresActive On
# すべてのコンテンツタイプのデフォルトTTL
ExpiresDefault "access plus 1 day"
# 画像:1か月間キャッシュ
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType image/webp "access plus 1 month"
# CSSとJavaScript:1週間キャッシュ
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
# フォント:1年間キャッシュ
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
# HTMLとデータ:キャッシュしない
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
</IfModule>
mod_headers の同等の設定
<IfModule mod_headers.c>
# 画像
<FilesMatch "\.(jpg|jpeg|png|gif|svg|webp)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
# CSSとJavaScript
<FilesMatch "\.(css|js)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
# フォント
<FilesMatch "\.(woff|woff2)$">
Header set Cache-Control "max-age=31536000, public, immutable"
</FilesMatch>
# HTMLとデータ:キャッシュしない
<FilesMatch "\.(html|json)$">
Header set Cache-Control "no-store"
</FilesMatch>
</IfModule>
グローバルなデフォルトTTLの設定
コンテンツの大部分が静的な場合は、グローバルなデフォルトを設定し、必要に応じて特定のタイプを上書きします。
mod_expires
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 week"
</IfModule>
mod_headers の同等の設定
<IfModule mod_headers.c>
Header set Cache-Control "max-age=604800, public"
</IfModule>
動的コンテンツのキャッシュ無効化
リクエストごとに変化するレスポンスを、CDN のエッジノードとブラウザーにキャッシュさせないようにします。
mod_expires
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
</IfModule>
mod_headers の同等の設定
<IfModule mod_headers.c>
<FilesMatch "\.(html|json|php)$">
Header set Cache-Control "no-store"
</FilesMatch>
</IfModule>
ディレクティブリファレンス
mod_expires ディレクティブ
|
ディレクティブ |
説明 |
|
|
サーバーまたはロケーションブロックに対して |
|
|
|
|
|
特定の MIME タイプの TTL を設定します。 |
時間ベースのオプション:
|
値 |
意味 |
|
|
TTL はリクエストの時刻から計算されます。 |
|
|
TTL はファイルの最終更新タイムスタンプから計算されます。 |
期間の単位:years、months、weeks、days、hours、minutes、seconds
一般的な期間の値:
|
式 |
相当 |
ユースケース |
|
|
31,536,000 秒 |
キャッシュバスティング用のファイル名を持つバージョニングされたアセット |
|
|
2,592,000 秒 |
画像やその他の更新頻度の低いアセット |
|
|
604,800 秒 |
CSS および JavaScript ファイル |
|
|
キャッシュなし |
HTML ページと API レスポンス |
設定の確認
Apache をリロードした後、ヘッダーがレスポンスに存在することを確認します。
curl -I https://<your-domain>/path/to/static-file.jpg
出力で Cache-Control または Expires を探します。
HTTP/1.1 200 OK
Cache-Control: max-age=2592000, public
Expires: Thu, 10 Jul 2026 04:00:00 GMT
または、Chrome DevTools を開き、[Network] タブに移動し、ページをリロードして静的リソースをクリックします。[Response Headers] パネルに、設定で指定した Cache-Control と Expires の値が表示されます。
ベストプラクティス
本番環境では
mod_headersを推奨します。mod_expiresでは生成できないCache-Controlの全ディレクティブ (no-store、immutable、stale-while-revalidate) をサポートしています。バージョニングされたアセットには長い TTL を使用します。ビルドパイプラインがファイル名にハッシュを追加する場合 (例:
app.a1b2c3.js)、TTL を 1 年以上に設定します。ファイル名の変更がキャッシュバスティングのメカニズムとして機能します。HTML と API レスポンスには
no-storeを設定してください。これにより、ブラウザーと CDN のエッジノードが常に最新のページ構造とデータを取得するようになります。再起動ではなく、リロードしてください。設定ファイルを編集した後、
apachectl graceful(またはsystemctl reload apache2/systemctl reload httpd) を実行して、アクティブな接続を切断せずに変更を適用します。本番環境に移行する前に
curl -Iでテストしてください。1 つだけでなく、設定した各コンテンツタイプでヘッダーを確認してください。