Deshabilite el almacenamiento en caché al servir archivos estáticos con Nginx (para desarrollo)

89

Estamos utilizando Nginx para servir archivos estáticos en una plataforma de desarrollo. Como es una plataforma de desarrollo, nos gustaría deshabilitar el almacenamiento en caché para que cada cambio se propague al servidor. La configuración del VHost es bastante simple:

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

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

Cuando accedemos a un archivo HTML ( http: //static.server.local/test.html ), no tenemos ningún problema: el servidor devuelve un código 304 No modificado siempre que el archivo no se modifique, y una respuesta 200 OK con el archivo modificado cuando se cambia el archivo.
Sin embargo, parece comportarse de manera diferente con un archivo Javascript o CSS. Una vez que se cambia el archivo, obtenemos una respuesta 200 OK como se esperaba, pero con el texto anterior.
¿Existe un mecanismo de caché interno en Nginx que podría explicar este comportamiento? ¿O alguna configuración que deberíamos agregar?

Como nota al margen, aquí está el encabezado devuelto por Nginx cuando el archivo ha sido modificado (parece correcto):

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

Editar
Después de probar diferentes configuraciones con la expiresdirectiva y el Cache-Controlencabezado, realicé algunas investigaciones adicionales. De hecho, el servidor está instalado en un Ubuntu VirtualBox invitado, y los datos se leen desde una carpeta compartida que se encuentra en el host Mac OSX.
Si el archivo se edita desde un IDE (NetBeans) en el host, parece que los cambios no aparecen, mientras que si lo edito directamente en el invitado (usando VIM), se actualiza.
Lo extraño es que no se comporta de manera similar con los archivos HTML.
Muy desconcertante.

Edición 2 (RESPUESTA)
De hecho, el origen del problema estaba más en el lado de VirtualBox. O más bien un conflicto entre VirtualBox y la opción "sendfile" del servidor.
Este enlace VirtualBox odia Sendfile me dio la solución: cambiar el sendfile indicador en la configuración del servidor de fuera :

sendfile  off;

Espero que esto también pueda ayudar a otras personas que usan VirtualBox para el desarrollo. :)
Hay información adicional en el foro VirtualBox .

Olivier Chappe
fuente
3
¿Estás ejecutando nginx en un vm vagabundo y estás usando fs compartido? Ha habido varios informes de sus síntomas usando esa combinación en #nginx.
kolbyjack
3
¡Literalmente podría abrazarte! Pasé 48 horas maldiciendo y volviéndome completamente loco con este problema exacto ..., volví a compilar nginx varias veces, sacrifiqué algunas criaturas pequeñas y esponjosas a varias deidades, aprendí las directivas de caché al revés ... todo para descubrir que es una rareza de línea para solucionar ¡Gracias a que VirtualBox es raro!
James Butler
13
Sería mucho más claro si publicara su respuesta como respuesta y la aceptara para que todos puedan ver que este problema se resolvió.
Zombaya
Fui golpeado por este error esta mañana. No me habría dado cuenta de que se debía a la carpeta compartida sin esto. ¡Gracias!
JaffaTheCake
¡Gracias! Según tengo entendido, no es otra forma de solucionar este error por ahora. ¿Qué pasa si necesito que sendfile esté habilitado? :-)
Dmitry Belaventsev

Respuestas:

57

Dado que la respuesta está de alguna manera oculta en la pregunta, aquí está la solución para nginx en un entorno VirtualBox como respuesta independiente.

En su configuración nginx (usualmente /etc/nginx/nginx.conf) o en el archivo de configuración vhost, cambie el sendfileparámetro a off:

sendfile  off;

Si bien sendfileestá en el corazón de la fama de Nginx (eficiencia de servicio de archivos estáticos ultrarrápidos de bajo nivel) podría ser una pesadilla para el desarrollo local, por ejemplo, los JavaScripts que cambian con frecuencia y necesitan ser recargados. No obstante, Nginx sendfile es inteligente y probablemente no sea un problema de la mayoría de las personas; ¡verifique también las opciones de "deshabilitar caché" de su navegador!

mono lorem
fuente
55
+1 aunque la respuesta debería explicar por qué es necesario en lugar de dejar que los lectores encuentren / relean la pregunta en busca de referencias. Haga que la respuesta sea independiente -> mejor.
AD7six
2
Esta parece ser la respuesta para mí. El problema parece ocurrir con la combinación específica de Sendfile, VirtualBox y un host OSX. abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett
sendfileestá bien incluso para un entorno de desarrollo local; es solo VirtualBox en el que está roto. Cuál es una razón (de muchas) recomiendo evitar VirtualBox ...
Michael Hampton
Gracias por guardar, extraño problema con Vagrant / VirtualBox / Ubuntu / Wordpress, supongo que mi entorno PROD está seguro con sendfile activado de forma predeterminada.
sonjz
Resuelve mi problema con nginx y docker
PascalTurbo
15

establece tu etiqueta de caducidad en

expires off;

y no debería establecer ningún encabezado caducado, también podría ser el almacenamiento en caché de su navegador incorrectamente

anthonysomerset
fuente
Desafortunadamente, he intentado esto también expires -1y el comportamiento sigue siendo el mismo.
Olivier Chappe
En cuanto al navegador, he pensado en estas posibilidades: primero estaba probando con Chrome, y después de modificar un archivo lo abrí por primera vez en Firefox: todavía obtuve la primera versión del archivo.
Olivier Chappe
también el encabezado de control de caché probablemente debería ser CACHE-CONTROL: NO-CACHE
anthonysomerset
o eliminar el encabezado de control de caché por completo - lo siento, no se
pudo
1
En Windows, "caduca" aún no deshabilita el almacenamiento en caché de archivos html. Súper frustrante cuando actualizo un archivo en mi IDE, pero! $ #% Ing nginx sirve una versión anterior.
Dan Dascalescu
2

Este es un error antiguo en VirtualBox (ver: # 819 , # 9069 , # 12597 , # 14920 ) donde vboxvfs parece tener algunos problemas con el acceso mmapped a los archivos que están sincronizados.

Esto puede suceder cuando edita el archivo fuera de la VM y espera ver el mismo cambio dentro de la VM.

Para solucionar este problema, debe deshabilitar la compatibilidad del archivo de envío del núcleo para entregar archivos al cliente deshabilitando la EnableSendfileopción . Esto es especialmente problemático para archivos montados en NFS o SMB.

ParaNginx (cambio en nginx.conf), p. Ej.

sendfile off;

Similar para Apache (en httpd.confo en el archivo vhosts), p. Ej.

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

Después del cambio, vuelva a cargar el Apache.


Otra posible solución es recordar no editar los archivos en el host, o intentar volver a editar el mismo archivo, pero dentro de la VM.


Otra solución alternativa incluye soltar el caché de páginas de Linux, por ejemplo

echo 1 > /proc/sys/vm/drop_caches

O para borrar los cachés cada segundo (según esta publicación ), intente:

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

Nota: El número 1 significa liberar el caché de página, 2 para dentries e inodes, 3 para pagecache, dentries e inodes.


El problema anterior puede ser replicado por el siguiente programa de pruebas de MMAP, ver: mmap-problem.c.

kenorb
fuente
1

Esto es tarde, pero todavía está marcado como sin respuesta, por lo que tomaré una puñalada. Solo por risas, ¿has probado:

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

No lo he intentado yo mismo, pero he aprendido a probar este tipo de cosas con Nginx en un contenedor de servidor de vez en cuando cuando tengo problemas similares a este ...

ColtonCat
fuente