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


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 souhaitons 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;
  } 
}

Quand on accède à un fichier HTML (http: //static.server.local/test.html), nous n'avons pas de problème: le serveur renvoie un code 304 non modifié tant que le fichier n'est pas modifié, et un 200 OK réponse avec le fichier modifié lorsque le fichier est modifié.
Cependant, il semble se comporter différemment avec un fichier Javascript ou CSS. Une fois le fichier modifié, nous obtenons un 200 OK réponse 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 réglages avec le expires directive et Cache-ControlEn-tête, j'ai effectué d'autres investigations. 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 n'apparaissent pas alors que 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 déteste Sendfile m'a donné la solution: changer le envoyer le fichier drapeau dans la configuration du serveur pour de:

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.


87
2018-05-13 14:18


origine


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
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 pour découvrir que c'est une étrange ligne à réparer Merci à VirtualBox d'être bizarre! - James Butler
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
Cela m'a beaucoup aidé. Je vous remercie. - Matt M.
J'ai été touché par ce bug ce matin. Je n'aurais pas réalisé que c'était dans le dossier partagé sans cela. Merci! - Jaffa The Cake


Réponses:


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 un fichier de configuration vhost, modifiez le sendfile paramètre à off:

sendfile  off;

Tandis que sendfile est au cœur de la renommée de Nginx (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. Les 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!


58
2017-11-19 09:52



+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
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
sendfile convient 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 - PascalTurbo


définir votre tag expires à

expires off;

et il ne doit pas du tout définir d'en-tête d'expiration, il se peut également que votre navigateur ne mette pas correctement en cache les fichiers


15
2018-05-13 14:20



Malheureusement, j'ai essayé cela ainsi que expires -1 et 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
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


Si rien de ce qui précède n’aide et que Nginx renvoie toujours l’ancien contenu de vos fichiers, il se peut que le problème soit lié à: open_file_cache.

Voir comme référence:


2
2017-10-14 20:38





C’est un vieux bogue dans VirtualBox (voir: # 819, # 9069, # 12597, # 14920) où vboxvfs semble rencontrer des problèmes d’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 le support du noyau sendfile afin de remettre des fichiers au client en désactivant EnableSendfile option. Cela est particulièrement problématique pour les fichiers montés NFS ou SMB.

Pour Nginx (changer nginx.conf), par exemple.

sendfile off;

Similaire pour Apache (en httpd.conf ou dans le 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 (selon ce post), 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 mmap-test suivant, voir: mmap-problem.c.


2
2017-12-13 14:03





C'est tard, mais toujours marqué sans réponse, je vais donc tenter 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 ...


1
2017-12-28 01:47