Aller au contenu

immutable: module NGINX pour définir un cache immuable sur les actifs statiques

Nécessite le plan Pro (ou supérieur) de l'abonnement GetPageSpeed NGINX Extras.

Installation

Vous pouvez installer ce module dans n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :

  • RedHat Enterprise Linux 7, 8, 9 et 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 et Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-immutable
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-immutable

Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :

load_module modules/ngx_http_immutable_module.so;

Ce document décrit nginx-module-immutable v0.0.7 publié le 20 mars 2026.


Coverity Scan Buy Me a Coffee

Ce petit module NGINX peut aider à améliorer le cache de vos actifs statiques publics, en définissant une expiration lointaine avec l'attribut immutable.

Public cible

Sites web et frameworks qui s'appuient sur le modèle de contournement du cache :

  • les ressources statiques incluent des versions/hachages dans leurs URL, tout en ne modifiant jamais les ressources
  • lorsque cela est nécessaire, mise à jour des ressources avec de nouvelles versions ayant de nouveaux numéros/hachages de version, de sorte que leurs URL soient différentes

Frameworks populaires qui utilisent le contournement du cache :

  • Magento 2
  • Ajoutez le vôtre ici !

Synopsis

http {
    server {
        location /static/ {
            immutable on;
        }
    }
}

produira l'en-tête HTTP suivant :

Cache-Control: public,max-age=31536000,stale-while-revalidate=31536000,stale-if-error=31536000,immutable

Remarque : Les clients HTTP/1.0 reçoivent un en-tête Expires: Thu, 31 Dec 2037 23:55:55 GMT au lieu de Cache-Control.

Comment cela diffère de expires max; :

  • Définit l'attribut immutable, par exemple Cache-Control: public,max-age=31536000,immutable pour un meilleur cache. C'est 1 an et non 10 ans, voir pourquoi ci-dessous.
  • Envoie Expires uniquement lorsque c'est vraiment nécessaire, par exemple lorsque un client demande des ressources via HTTP/1.0
  • Définit l'attribut public pour s'assurer que les actifs peuvent être mis en cache par des caches publics, ce qui est généralement souhaitable.

En raison du manque de support de immutable dans les navigateurs basés sur Chromium, nous ajoutons également stale-while-revalidate=31536000,stale-if-error=31536000, ce qui aide à améliorer le taux de réussite du cache dans des cas extrêmes. L'utilisation de ces directives permet de servir des réponses mises en cache au-delà de leur durée de vie de cache, ce qui est éternel dans le cas de ressources immuables.

Ainsi, dans la plupart des cas, immutable on; peut être utilisé comme une meilleure alternative à expires max; pour mettre en œuvre le modèle de contournement du cache.

Directives

immutable

Syntaxe : immutable on | off;

Par défaut : immutable off;

Contexte : http, server, location

Active ou désactive les en-têtes de cache immuable pour l'emplacement.

immutable_cache_status

Syntaxe : immutable_cache_status on | off;

Par défaut : immutable_cache_status off;

Contexte : http, server, location

Active l'en-tête RFC 9211 Cache-Status pour le débogage et l'observabilité. Lorsqu'il est activé, les réponses incluent :

Cache-Status: "nginx/immutable"; hit; ttl=31536000

Cet en-tête aide à déboguer le comportement de mise en cache à travers des architectures de mise en cache multi-couches (NGINX -> CDN -> Navigateur). Chaque couche de cache peut ajouter son propre statut, créant une chaîne comme :

Cache-Status: "nginx/immutable"; hit; ttl=31536000, "cloudflare"; fwd=uri-miss; stored

Configuration d'exemple :

location /static/ {
    immutable on;
    immutable_cache_status on;
}

immutable_types

Syntaxe : immutable_types mime-type ...;

Par défaut : (aucun - s'applique à tous les types lorsqu'il n'est pas spécifié)

Contexte : http, server, location

Restreint les en-têtes de cache immuable aux réponses avec les types MIME spécifiés. Lorsqu'il n'est pas spécifié, les en-têtes immuables s'appliquent à toutes les réponses. Cela est similaire à la façon dont gzip_types fonctionne pour le module gzip.

Configuration d'exemple :

location /static/ {
    immutable on;
    # Appliquer uniquement les en-têtes immuables aux fichiers JavaScript et CSS
    immutable_types application/javascript text/css;
}

Pourquoi 31536000 secondes (1 an ?)

La RFC définit l'utilisation d'un an pour faire d'une réponse un "jamais expiré" :

Pour marquer une réponse comme “jamais expirée”, un serveur d'origine envoie une date d'expiration environ un an après l'envoi de la réponse. Les serveurs HTTP/1.1 NE DOIVENT PAS envoyer de dates d'expiration plus d'un an dans le futur.

Plus de détails dans l'article.

Paquets Ubuntu et Debian

Il est facile d'installer le paquet du module pour ces systèmes d'exploitation.

ngx_immutable fait partie de la collection APT NGINX Extras, vous pouvez donc l'installer avec tous les modules, y compris Brotli.

Tout d'abord, configurez le dépôt, puis :

sudo apt-get update
sudo apt-get install nginx-module-immutable

Exemple : configuration de production Magento 2

À condition que votre boutique fonctionne en mode production, vous avez déjà compilé tous les actifs. Cette configuration d'exemple peut être optimisée comme suit :

location /static/ {
    immutable on;

    # Supprimer la signature des fichiers statiques qui est utilisée pour contourner le cache du navigateur
    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        immutable off;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

Lorsqu'il est utilisé avec ngx_security_headers, il peut être simplifié davantage :

security_headers on;

location /static/ {
    immutable on;

    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        immutable off;
    }
}