Apache キャッシュポリシーの設定

更新日時
Copy as MD

Apache オリジンサーバーで mod_expires または mod_headers を設定して Cache-Control および Expires レスポンスヘッダーを設定し、Alibaba Cloud CDN のエッジノードとブラウザーが静的コンテンツを適切な Time to Live (TTL) でキャッシュするようにします。

モジュールの選択

Apache は、キャッシュヘッダーを制御するために 2 つのモジュールを提供しています。要件に応じて選択してください。

モジュール

利点

欠点

使用シナリオ

mod_expires

シンプルな構文です。MIME タイプごとに ExpiresCache-Control: max-age を迅速に設定できます。

no-storeimmutable などの複雑なディレクティブは設定できません。

max-age のみが必要なシンプルなシナリオ。

mod_headers

Cache-Control ヘッダーを完全に制御できます。immutable を含むすべてのディレクティブをサポートします。

構文が若干複雑です。

きめ細かいキャッシュポリシーが必要な本番環境。

前提条件

開始する前に、必要な Apache モジュールが有効になっていることを確認します。

どのモジュールが読み込まれているかを確認します。

apachectl -M | grep -E "expires|headers"

出力には expires_moduleheaders_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 ディレクティブ

ディレクティブ

説明

ExpiresActive On

サーバーまたはロケーションブロックに対して Expires ヘッダーの生成を有効にします。

ExpiresDefault "<base> plus <duration>"

ExpiresByType に一致しないすべてのコンテンツタイプのデフォルト TTL を設定します。

ExpiresByType <MIME-type> "<base> plus <duration>"

特定の MIME タイプの TTL を設定します。

時間ベースのオプション:

意味

access / now

TTL はリクエストの時刻から計算されます。

modification

TTL はファイルの最終更新タイムスタンプから計算されます。

期間の単位:yearsmonthsweeksdayshoursminutesseconds

一般的な期間の値:

相当

ユースケース

"access plus 1 year"

31,536,000 秒

キャッシュバスティング用のファイル名を持つバージョニングされたアセット

"access plus 1 month"

2,592,000 秒

画像やその他の更新頻度の低いアセット

"access plus 1 week"

604,800 秒

CSS および JavaScript ファイル

"access plus 0 seconds"

キャッシュなし

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-ControlExpires の値が表示されます。

ベストプラクティス

  • 本番環境では mod_headers を推奨します。mod_expires では生成できない Cache-Control の全ディレクティブ (no-storeimmutablestale-while-revalidate) をサポートしています。

  • バージョニングされたアセットには長い TTL を使用します。ビルドパイプラインがファイル名にハッシュを追加する場合 (例:app.a1b2c3.js)、TTL を 1 年以上に設定します。ファイル名の変更がキャッシュバスティングのメカニズムとして機能します。

  • HTML と API レスポンスには no-store を設定してください。これにより、ブラウザーと CDN のエッジノードが常に最新のページ構造とデータを取得するようになります。

  • 再起動ではなく、リロードしてください。設定ファイルを編集した後、apachectl graceful (または systemctl reload apache2 / systemctl reload httpd) を実行して、アクティブな接続を切断せずに変更を適用します。

  • 本番環境に移行する前に curl -I でテストしてください。1 つだけでなく、設定した各コンテンツタイプでヘッダーを確認してください。