Désactiver la mise en cache lors du traitement de fichiers statiques avec Nginx (pour le développement)

89

Nous utilisons Nginx pour servir des fichiers statiques sur une plate-forme de développement. S'agissant d'une plate-forme de développement, nous aimerions désactiver la mise en cache afin que chaque modification soit propagée au serveur. La configuration du VHost est assez simple:

server {
  server_name  static.server.local;
  root /var/www/static;

  ## Default location
  location / {
    access_log        off;
    expires           0;
    add_header        Cache-Control private;
  } 
}

Lorsque nous accédons à un fichier HTML ( http: //static.server.local/test.html ), nous n’avons aucun problème: le serveur renvoie un code 304 non modifié tant que le fichier n’a pas été modifié et une réponse 200 OK avec le fichier modifié lors de la modification du fichier.
Cependant, il semble se comporter différemment avec un fichier Javascript ou CSS. Une fois le fichier modifié, nous obtenons une réponse 200 OK comme prévu, mais avec l'ancien texte.
Existe-t-il un mécanisme de cache interne dans Nginx qui pourrait expliquer ce comportement? Ou une configuration que nous devrions ajouter?

En remarque, voici l'en-tête renvoyé par Nginx lorsque le fichier a été modifié (cela semble correct):

Accept-Ranges:bytes
Cache-Control:max-age=0
private
Connection:keep-alive
Content-Length:309
Content-Type:text/css
Date:Fri, 13 May 2011 14:13:13 GMT
Expires:Fri, 13 May 2011 14:13:13 GMT
Last-Modified:Fri, 13 May 2011 14:13:05 GMT
Server:nginx/0.8.54

Modifier
Après avoir essayé différents paramètres avec la expiresdirective et l’en- Cache-Controltête, j’ai effectué quelques recherches supplémentaires. En fait, le serveur est installé sur un invité VirtualBox Ubuntu et les données sont lues à partir d'un dossier partagé situé sur l'hôte Mac OSX.
Si le fichier est modifié à partir d'un IDE (NetBeans) sur l'hôte, il semble que les modifications ne s'affichent pas. Si je le modifie directement sur l'invité (à l'aide de VIM), il est actualisé.
La chose étrange est qu'il ne se comporte pas de la même manière avec les fichiers HTML.
Assez curieux.

Edit 2 (REPONSE)
En effet, l'origine du problème était davantage du côté de VirtualBox. Ou plutôt un conflit entre VirtualBox et l'option "sendfile" du serveur.
Ce lien VirtualBox Hates Sendfile m'a donné la solution: changer le sendfile drapeau dans la configuration du serveur hors :

sendfile  off;

J'espère que cela pourrait également aider une autre personne utilisant VirtualBox pour son développement. :)
Il y a quelques informations supplémentaires sur le forum VirtualBox .

Olivier Chappe
la source
3
Exécutez-vous nginx dans une machine virtuelle vagabonde et utilisez-vous des f partagées? Il y a eu plusieurs rapports de vos symptômes utilisant cette combinaison dans #nginx.
Kolbyjack
3
Je pourrais littéralement t'embrasser !! J'ai passé 48 heures à maudire et à devenir complètement fou de ce problème .., a recompilé nginx à quelques reprises, sacrifié quelques petites créatures moelleuses à diverses divinités, a appris les directives du cache à l'envers ... tout cela pour découvrir qu'il s'agit d'une étrange ligne à réparer merci à VirtualBox d'être bizarre!
James Butler
13
Il serait beaucoup plus clair de poster votre réponse comme réponse et de l'accepter afin que tout le monde puisse voir que ce problème a été résolu.
Zombaya
J'ai été touché par ce virus ce matin. Je n'aurais pas réalisé que c'était dans le dossier partagé sans cela. Merci!
JaffaTheCake
Merci! Si j'ai bien compris, ce n'est pas un autre moyen de résoudre ce problème pour l'instant? Que faire si j'ai besoin que sendfile soit activé? :-)
Dmitry Belaventsev

Réponses:

57

Puisque la réponse est en quelque sorte cachée dans la question, voici la solution pour nginx dans un environnement VirtualBox en tant que réponse autonome.

Dans votre configuration nginx (généralement /etc/nginx/nginx.conf) ou dans le fichier de configuration vhost, définissez le sendfileparamètre sur off:

sendfile  off;

Si sendfileNginx est au cœur de la renommée (efficacité des fichiers statiques de bas niveau extrêmement rapides), il pourrait s’agir d’un fléau pour le développement local, par exemple, des javascripts qui changent souvent et doivent être rechargés. Néanmoins, Nginx sendfile est intelligent et n’est probablement pas le problème de la plupart des gens; Vérifiez également les options "Désactiver le cache" de votre navigateur!

lorem singe
la source
5
+1 si la réponse devrait expliquer pourquoi cela est nécessaire au lieu de laisser les lecteurs chercher / relire la question à la recherche de références. Faites en sorte que la réponse soit autonome -> meilleure.
AD7six
2
Cela semble être la réponse pour moi. Le problème semble se produire avec la combinaison spécifique de Sendfile, VirtualBox et un hôte OSX. abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett Le
sendfileconvient même pour un environnement de développement local; c'est seulement VirtualBox dans lequel c'est cassé. Quelle est l'une des raisons pour lesquelles je recommande d'éviter VirtualBox ...
Michael Hampton
merci pour la sauvegarde, étrange problème avec Vagrant / VirtualBox / Ubuntu / Wordpress, je suppose que mon environnement de production est sécurisé avec sendfile activé par défaut.
Sonjz
Résout mon problème avec nginx et docker
Pascal Turbo
15

définissez votre tag expires sur

expires off;

et il ne devrait pas du tout définir d'en-têtes d'expiration, cela pourrait également être la mise en cache incorrecte des fichiers par votre navigateur

anthonysomerset
la source
Malheureusement, j'ai essayé cela aussi expires -1et le comportement est toujours le même.
Olivier Chappe
En ce qui concerne le navigateur, j’ai pensé aux possibilités suivantes: j’essayais d’abord avec Chrome et, après avoir modifié un fichier, je l’avais ouvert pour la première fois dans Firefox: j’avais toujours la première version du fichier.
Olivier Chappe
aussi l'en-tête cache-control devrait probablement être CACHE-CONTROL: NO-CACHE
anthonysomerset
ou supprimer complètement l'en-tête de contrôle du cache - désolé, impossible de modifier le commentaire précédent
anthonysomerset
1
Sous Windows, "expire hors" ne désactive toujours pas la mise en cache des fichiers HTML. Super frustrant lorsque je mets à jour un fichier dans mon IDE, mais! $ #% Ing nginx sert une ancienne version.
Dan Dascalescu
2

Ceci est un vieux bogue dans VirtualBox (voir: # 819 , # 9069 , # 12597 , # 14920 ) où vboxvfs semble avoir quelques problèmes avec l’accès mappé aux fichiers synchronisés.

Cela peut se produire lorsque vous modifiez le fichier en dehors de la VM et que vous vous attendez à voir le même changement dans la VM.

Pour résoudre ce problème, vous devez désactiver la prise en charge du noyau sendfile afin de remettre des fichiers au client en désactivant l' EnableSendfileoption . Cela est particulièrement problématique pour les fichiers montés NFS ou SMB.

PourNginx (changer nginx.conf), par exemple

sendfile off;

Similaire pour Apache (dans httpd.confou dans un fichier vhosts), par exemple

<Directory "/path-to-nfs-files">
  EnableSendfile Off
</Directory>

Après le changement, rechargez Apache.


Une autre solution potentielle est simplement de ne pas éditer les fichiers sur l'hôte ou d'essayer de rééditer le même fichier, mais au sein de la machine virtuelle.


Une autre solution consiste à supprimer le pagecache Linux, par exemple

echo 1 > /proc/sys/vm/drop_caches

Ou pour vider les caches toutes les secondes (comme dans cet article ), essayez:

watch -n 1 $(sync; echo 1 > /proc/sys/vm/drop_caches)

Remarque: Le numéro 1 signifie libérer le pagecache, 2 pour les dentries et les inodes, 3 pour le pagecache, les dentries et les inodes.


Le problème ci - dessus peut être reproduit par le programme de test de mmap suivant, voir: mmap-problem.c.

Kenorb
la source
1

C'est tard, mais toujours marqué sans réponse, donc je vais prendre un coup de poignard. Juste pour rire, avez-vous essayé:

location ~* \.(css|js)$ {
    expires 0;
    break;
}

Je n'ai pas essayé cela moi-même, mais j'ai appris à essayer ce genre de chose avec Nginx dans un conteneur de serveur de temps en temps lorsque j'ai des problèmes similaires à ceux-ci ...

ColtonCat
la source