Caching deaktivieren, wenn statische Dateien mit Nginx bereitgestellt werden (für die Entwicklung)

89

Wir verwenden Nginx, um statische Dateien auf einer Entwicklungsplattform bereitzustellen. Da es sich um eine Entwicklungsplattform handelt, möchten wir das Caching deaktivieren, damit jede Änderung auf den Server übertragen wird. Die Konfiguration des VHost ist ganz einfach:

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

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

Wenn wir auf eine HTML-Datei ( http: //static.server.local/test.html ) zugreifen , tritt kein Problem auf: Der Server gibt einen Code 304 "Nicht geändert" zurück , solange die Datei nicht geändert wird, und eine 200-OK- Antwort mit die geänderte Datei, wenn die Datei geändert wird.
Bei einer Javascript- oder CSS-Datei scheint es sich jedoch anders zu verhalten. Sobald die Datei geändert wurde, erhalten wir erwartungsgemäß eine Antwort in Höhe von 200 OK , jedoch mit dem alten Text.
Gibt es einen internen Cache-Mechanismus in Nginx, der dieses Verhalten erklären könnte? Oder eine Konfiguration, die wir hinzufügen sollten?

Als Randnotiz ist hier der Header, der von Nginx zurückgegeben wird, wenn die Datei geändert wurde (es scheint korrekt zu sein):

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

Bearbeiten
Nachdem ich verschiedene Einstellungen mit der expiresDirektive und der Cache-ControlKopfzeile ausprobiert hatte , führte ich einige weitere Untersuchungen durch. Tatsächlich ist der Server auf einem VirtualBox-Gast-Ubuntu installiert, und die Daten werden aus einem freigegebenen Ordner gelesen, der sich auf dem Mac OSX-Host befindet.
Wenn die Datei von einer IDE (NetBeans) auf dem Host bearbeitet wird, werden anscheinend keine Änderungen angezeigt. Wenn ich sie direkt auf dem Gast (mit VIM) bearbeite, wird sie aktualisiert.
Das Seltsame ist, dass es sich bei HTML-Dateien nicht ähnlich verhält.
Ziemlich rätselhaft.

Edit 2 (ANTWORT)
Tatsächlich lag der Ursprung des Problems eher auf der VirtualBox-Seite. Oder vielmehr ein Konflikt zwischen VirtualBox und der Option "sendfile" des Servers.
Dieser Link VirtualBox Hates Sendfile gab mir die Lösung: Schalten Sie das Sendfile- Flag in der Serverkonfiguration aus :

sendfile  off;

Hoffe, dies könnte auch anderen Personen helfen, die VirtualBox für die Entwicklung verwenden. :)
Es gibt einige zusätzliche Informationen im VirtualBox-Forum .

Olivier Chappe
quelle
3
Führen Sie Nginx in einem Vagabund aus und verwenden Sie gemeinsam genutzte Fs? Es gab mehrere Berichte über Ihre Symptome bei Verwendung dieser Kombination in #nginx.
Kolbyjack
3
Ich könnte dich buchstäblich umarmen !! Habe 48 Stunden damit verbracht, zu fluchen und völlig verrückt zu werden mit diesem Problem., Habe ein paar Mal Nginx neu kompiliert, ein paar kleine flauschige Kreaturen verschiedenen Gottheiten geopfert, die Cache-Direktiven rückwärts gelernt ... alles um herauszufinden, dass es eine seltsame Sache ist dank VirtualBox wird komisch!
James Butler
13
Es wäre viel klarer, wenn Sie Ihre Antwort als Antwort posten und akzeptieren würden, damit jeder sehen kann, dass dieses Problem gelöst wurde.
Zombaya
Ich wurde heute Morgen von diesem Käfer getroffen. Ohne dies hätte ich nicht bemerkt, dass es sich um einen freigegebenen Ordner handelt. Vielen Dank!
JaffaTheCake
Vielen Dank! Wie ich verstehe, gibt es keine andere Möglichkeit, diesen Fehler vorerst zu beheben? Was ist, wenn ich sendfile aktivieren muss? :-)
Dmitry Belaventsev

Antworten:

57

Da die Antwort irgendwie in der Frage verborgen ist - hier ist die Lösung für Nginx in einer VirtualBox-Umgebung als eigenständige Antwort.

Ändern Sie in Ihrer Nginx-Konfiguration (normalerweise /etc/nginx/nginx.conf) oder in der VHOST-Konfigurationsdatei den sendfileParameter in off:

sendfile  off;

Während sendfileNginx im Mittelpunkt seines Ruhms steht (blitzschnelle statische Dateien auf niedriger Ebene dienen der Effizienz), könnte es ein Fluch für die lokale Entwicklung sein, z. B. Javascripts, die häufig geändert werden und neu geladen werden müssen. Nichtsdestotrotz ist Nginx sendfile intelligent und wahrscheinlich nicht das Problem der meisten Menschen. Überprüfen Sie auch die "Cache deaktivieren" -Optionen Ihres Browsers!

Lorem Affe
quelle
5
+1 obwohl die Antwort erklären sollte, warum dies notwendig ist, anstatt es den Lesern effektiv zu überlassen, die Frage nach Referenzen zu suchen / erneut zu lesen. Lassen Sie die Antwort für sich stehen -> besser.
AD7six
2
Dies scheint die Antwort für mich zu sein. Das Problem scheint bei der bestimmten Kombination von Sendfile, VirtualBox und einem OSX-Host aufzutreten. abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett
sendfileist auch für eine lokale Entwicklungsumgebung in Ordnung; Es ist nur VirtualBox, in der es kaputt ist. Welches ist ein Grund (von vielen) Ich empfehle die Vermeidung von VirtualBox ...
Michael Hampton
Vielen Dank für das sichere, seltsame Problem mit Vagrant / VirtualBox / Ubuntu / Wordpress. Ich gehe davon aus, dass meine PROD-Umgebung mit sendfile als Standard sicher ist.
sonjz
Löst mein Problem mit
Nginx
15

Setzen Sie Ihr Expires-Tag auf

expires off;

und es sollten überhaupt keine ablaufenden Header gesetzt werden, es könnte auch sein, dass Ihr Browser Dateien falsch zwischenspeichert

Anthonysomerset
quelle
Leider habe ich das auch probiert expires -1und das Verhalten ist immer noch das gleiche.
Olivier Chappe
Bezüglich des Browsers habe ich über diese Möglichkeiten nachgedacht: Ich habe es zuerst mit Chrome versucht und nach dem Ändern einer Datei diese zum ersten Mal in Firefox geöffnet: Ich habe immer noch die erste Version der Datei.
Olivier Chappe
auch der Cache-Control-Header sollte wahrscheinlich CACHE-CONTROL sein: NO-CACHE
Anthonysomerset
oder entfernen Sie den Cache-Steuerelement-Header insgesamt - der vorherige Kommentar konnte leider nicht bearbeitet werden
anthonysomerset
1
Unter Windows deaktiviert "expires off" das Zwischenspeichern von HTML-Dateien immer noch nicht. Super frustrierend, wenn ich eine Datei in meiner IDE aktualisiere, aber! $ #% Ing nginx liefert eine alte Version.
Dan Dascalescu
2

Dies ist ein alter Fehler in VirtualBox (siehe: # 819 , # 9069 , # 12597 , # 14920 ), bei dem vboxvfs einige Probleme mit dem Zugriff auf synchronisierte Dateien zu haben scheint.

Dies kann passieren, wenn Sie die Datei außerhalb der VM bearbeiten und erwarten, dass dieselbe Änderung innerhalb der VM vorgenommen wird.

Um dieses Problem zu umgehen, müssen Sie die Kernel-Sendefile-Unterstützung deaktivieren, um Dateien an den Client zu liefern, indem Sie die EnableSendfileOption deaktivieren . Dies ist insbesondere für NFS- oder SMB-gemountete Dateien problematisch.

FürNginx (Wechsel in nginx.conf), z

sendfile off;

Ähnlich für Apache (in httpd.confoder in vhosts-Datei), z

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

Nach der Änderung den Apache neu laden.


Eine andere mögliche Lösung besteht darin, die Dateien auf dem Host nicht zu bearbeiten oder zu versuchen, dieselbe Datei erneut zu bearbeiten, jedoch innerhalb der VM.


Eine weitere Problemumgehung besteht darin, den Linux-Pagecache zu löschen, z

echo 1 > /proc/sys/vm/drop_caches

Oder, um die Caches jede Sekunde zu löschen (wie in diesem Beitrag beschrieben ), versuchen Sie Folgendes:

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

Hinweis: Nummer 1 steht für das Freigeben von Pagecache, 2 für Einträge und Inodes, 3 für Pagecache, Einträge und Inodes.


Das obige Problem kann durch die folgende mmap-Testprogramm repliziert werden, finden Sie unter : mmap-problem.c.

Kenorb
quelle
1

Dies ist spät, aber immer noch als unbeantwortet markiert, also werde ich einen Stich machen. Haben Sie es nur versucht, um zu kichern:

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

Ich habe das noch nicht selbst ausprobiert, aber ich habe von Zeit zu Zeit gelernt, so etwas mit Nginx in einem Server-Container zu versuchen, wenn ich ähnliche Probleme habe ...

ColtonCat
quelle