Nous utilisons Nginx pour servir des fichiers statiques sur une plateforme de développement. Comme il s'agit 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'est pas modifié et une réponse 200 OK 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 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é (il 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 directive expires
et Cache-Control
header, j'ai fait d'autres investigations. En fait, le serveur est installé sur un Ubuntu invité VirtualBox, et les données sont lues à partir d'un dossier partagé qui se trouve sur l'hôte Mac OSX.
Si le fichier est édité à partir d'un IDE (NetBeans) sur l'hôte, il semble que les changements n'apparaissent pas alors que si je le modifie directement sur l'invité (en utilisant VIM), il est rafraîchi.
Ce qui est étrange, c'est qu'il ne se comporte pas de la même manière avec les fichiers HTML.
Assez déroutant.
Modifier 2 (RÉPONSE)
En effet, l'origine du problème était plutôt 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: basculez l'indicateur sendfile dans la configuration du serveur sur désactivé :
sendfile off;
J'espère que cela pourrait également aider une autre personne à utiliser VirtualBox pour le développement. :)
Il y a quelques informations supplémentaires sur le forum VirtualBox .
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 fichier de configuration nginx (généralement /etc/nginx/nginx.conf) ou vhost, changez le paramètre sendfile
en off
:
sendfile off;
Alors que sendfile
est au cœur de la renommée de Nginx (efficacité des fichiers statiques de bas niveau ultra rapides), cela pourrait être un fléau pour le développement local, par exemple 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!
définissez votre balise expirée sur
expires off;
et il ne doit pas définir d'en-têtes expirés du tout, il peut également s'agir de la mise en cache incorrecte des fichiers par votre navigateur
Si rien de mentionné ci-dessus ne vous aide et que Nginx retourne toujours l'ancien contenu de vos fichiers, il peut s'agir d'un problème lié à open_file_cache
.
Voir comme référence:
Il s'agit d'un ancien bogue dans VirtualBox (voir: # 819 , # 9069 , # 12597 , # 1492 ) où vboxvfs semble avoir quelques problèmes avec l'accès mmappé aux fichiers qui sont synchronisés.
Cela peut se produire lorsque vous modifiez le fichier en dehors de la machine virtuelle et que vous vous attendez à voir le même changement au sein de la machine virtuelle.
Pour contourner ce problème, vous devez désactiver la prise en charge du fichier d'envoi du noyau pour remettre les fichiers au client en désactivant option EnableSendfile
. Ceci est particulièrement problématique pour NFS ou SMB fichiers montés.
Pour Nginx
(changement dans nginx.conf
), par exemple.
sendfile off;
Similaire pour Apache (dans httpd.conf
ou dans le fichier vhosts), par exemple.
<Directory "/path-to-nfs-files">
EnableSendfile Off
</Directory>
Après la modification, rechargez Apache.
Une autre solution potentielle consiste à ne pas modifier les fichiers sur l'hôte ou à essayer de rééditer le même fichier, mais dans la machine virtuelle.
Une autre solution de contournement consiste à supprimer la pagecache Linux, par exemple.
echo 1 > /proc/sys/vm/drop_caches
Ou pour effacer les caches toutes les secondes (selon cet article ), essayez:
watch -n 1 $(sync; echo 1 > /proc/sys/vm/drop_caches)
Remarque: Le numéro 1 représente la libération de pagecache, 2 pour les dentiers et les inodes, 3 pour la pagecache, les dentiers et les inodes.
Le problème ci-dessus peut être répliqué par le programme de test mmap suivant, voir: mmap-problem.c
.
C'est en retard, mais toujours marqué sans réponse, donc je vais essayer. 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 quand j'ai des problèmes similaires à cela ...