Desabilitar o armazenamento em cache ao exibir arquivos estáticos com o Nginx (para desenvolvimento)

89

Estamos usando o Nginx para servir arquivos estáticos em uma plataforma de desenvolvimento. Como é uma plataforma de desenvolvimento, gostaríamos de desativar o cache para que cada alteração seja propagada para o servidor. A configuração do VHost é bastante simples:

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

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

Quando acessamos um arquivo HTML ( http: //static.server.local/test.html ), não temos problema: o servidor retorna um código 304 Não modificado , desde que o arquivo não seja alterado e uma resposta 200 OK com o arquivo modificado quando o arquivo é alterado.
No entanto, parece se comportar de maneira diferente com um arquivo Javascript ou CSS. Depois que o arquivo é alterado, obtemos uma resposta 200 OK, conforme o esperado, mas com o texto antigo.
Existe um mecanismo de cache interno no Nginx que possa explicar esse comportamento? Ou alguma configuração que devemos adicionar?

Como uma observação lateral, aqui está o cabeçalho retornado pelo Nginx quando o arquivo foi modificado (parece correto):

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
Depois de tentar configurações diferentes com a expiresdiretiva e o Cache-Controlcabeçalho, fiz algumas investigações adicionais. De fato, o servidor está instalado em um Ubuntu convidado do VirtualBox e os dados são lidos em uma pasta compartilhada que está no host do Mac OSX.
Se o arquivo for editado a partir de um IDE (NetBeans) no host, parece que as alterações não aparecerão; se eu o editar diretamente no convidado (usando o VIM), ele será atualizado.
O estranho é que não se comporta de maneira semelhante com arquivos HTML.
Bastante intrigante.

Editar 2 (RESPOSTA)
Na verdade, a origem do problema estava mais no lado do VirtualBox. Ou melhor, um conflito entre o VirtualBox e a opção "sendfile" do servidor.
Este link VirtualBox deia Sendfile me deu a solução: mudar o sendfile bandeira na configuração do servidor para fora :

sendfile  off;

Espero que isso também ajude outra pessoa usando o VirtualBox para desenvolvimento. :)
Há algumas informações adicionais no fórum do VirtualBox .

Olivier Chappe
fonte
3
Você está executando o nginx em uma vm vagrant e usando fs compartilhados? Houve vários relatos de seus sintomas usando essa combinação no #nginx.
Kolbyjack 13/05
3
Eu poderia literalmente te abraçar !! Passei 48 horas xingando e enlouquecendo completamente com esse problema exato, recompilou o nginx algumas vezes, sacrificou algumas pequenas criaturas fofas para deidades variadas, aprendeu as diretivas de cache ao contrário ... tudo para descobrir que é uma esquisitice uma linha para corrigir graças ao VirtualBox ser estranho!
James Butler
13
Seria muito mais claro se você colocasse sua resposta como resposta e a aceitas para que todos possam ver que esse problema foi resolvido.
Zombaya
Fui atingido por esse bug esta manhã. Não teria percebido que estava na pasta compartilhada sem isso. Obrigado!
JaffaTheCake
Valeu! Pelo que entendi, não há outra maneira de corrigir esse bug por enquanto? E se eu precisar que o sendfile esteja habilitado? :-) #
687 Dmitry Belaventsev

Respostas:

57

Como a resposta está de alguma forma oculta na pergunta - aqui está a solução para o nginx em um ambiente VirtualBox como resposta autônoma.

Em seu arquivo de configuração nginx (geralmente /etc/nginx/nginx.conf) ou vhost config, altere o sendfileparâmetro para off:

sendfile  off;

Embora sendfileesteja no cerne da fama do Nginx (arquivos estáticos de baixo nível que atendem a eficiência), pode ser uma desgraça para o desenvolvimento local, por exemplo, Javascripts que mudam frequentemente e precisam ser recarregados. No entanto, o Nginx sendfile é inteligente e provavelmente não é um problema da maioria das pessoas; verifique as opções de "desativar cache" do seu navegador também!

macaco lorem
fonte
5
+1, embora a resposta explique por que isso é necessário, em vez de deixar efetivamente os leitores a encontrar / reler a pergunta em busca de referências. Faça a resposta por si própria -> melhor.
AD7six
2
Esta parece ser a resposta para mim. O problema parece ocorrer com a combinação específica de Sendfile, VirtualBox e um host OSX. abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett
sendfileé bom mesmo para um ambiente de desenvolvimento local; é apenas o VirtualBox no qual está quebrado. Que é uma razão (de muitos) que eu recomendo evitar VirtualBox ...
Michael Hampton
obrigado pela questão estranha e salva do Vagrant / VirtualBox / Ubuntu / Wordpress, acho que meu ambiente PROD está seguro com o sendfile ativado como padrão.
sonjz
Resolve meu problema com nginx e estivador
PascalTurbo
15

defina sua tag expirar como

expires off;

e não deve definir nenhum cabeçalho de expiração, também pode ser o navegador que está armazenando arquivos incorretamente em cache

anthonysomerset
fonte
Infelizmente, eu tentei isso também expires -1e o comportamento ainda é o mesmo.
Olivier Chappe
Em relação ao navegador, pensei nessas possibilidades: estava tentando primeiro com o Chrome e, depois de modificar um arquivo, abri-o pela primeira vez no Firefox: ainda recebi a primeira versão do arquivo.
Olivier Chappe
também o cabeçalho de controle de cache deve ser provavelmente Cache-Control: no-cache
anthonysomerset
ou remover o cabeçalho de controle de cache completamente - desculpe edição não poderia comentário anterior
anthonysomerset
1
No Windows, "expira" ainda não desativa o cache de arquivos html. Super frustrante quando eu atualizo um arquivo no meu IDE, mas! $ #% Ing nginx serve uma versão antiga.
Dan Dascalescu
2

Este é um bug antigo no VirtualBox (consulte: # 819 , # 9069 , # 12597 , # 14920 ), em que o vboxvfs parece ter alguns problemas com o acesso mmappedado aos arquivos sincronizados.

Isso pode acontecer quando você edita o arquivo fora da VM e espera ver a mesma alteração na VM.

Para solucionar esse problema, você precisa desativar o kernel sendfile apoiar para entregar arquivos para o cliente, desativando EnableSendfileopção . Isso é especialmente problemático para arquivos montados em NFS ou SMB.

ParaNginx (alteração nginx.conf), por exemplo

sendfile off;

Semelhante para o Apache (no httpd.confarquivo ou no vhosts), por exemplo

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

Após a alteração, recarregue o Apache.


Outra solução potencial é apenas lembrar de não editar os arquivos no host ou tentar reeditar o mesmo arquivo, mas dentro da VM.


Outra solução alternativa é descartar o pagecache do Linux, por exemplo

echo 1 > /proc/sys/vm/drop_caches

Ou, para limpar os caches a cada segundo (conforme esta postagem ), tente:

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

Nota: O número 1 significa libertar pagecache, 2 para dentries e inodes, 3 para pagecache, dentries e inodes.


O problema acima pode ser replicado pelo seguinte programa mmap-teste, consulte: mmap-problem.c.

kenorb
fonte
1

É tarde, mas ainda está marcado como sem resposta, então vou dar uma facada. Apenas para rir, você já tentou:

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

Ainda não tentei isso, mas aprendi a tentar esse tipo de coisa com o Nginx em um contêiner de servidor de tempos em tempos, quando eu tenho problemas semelhantes a este ...

ColtonCat
fonte