nginx + django servindo arquivos estáticos

6

Eu segui as instruções para configurar o django com nginx a partir do wiki do django ( link ) e ter a configuração nginx da seguinte forma (algumas mudanças de nome para ajustar minha configuração).

    user  nginx nginx;

worker_processes  2;

error_log /var/log/nginx/error_log info;

events {
    worker_connections  1024;
    use epoll;
}

http {
    include     /etc/nginx/mime.types;
    default_type    application/octet-stream;

    log_format main
        '$remote_addr - $remote_user [$time_local] '
            '"$request" $status $bytes_sent '
        '"$http_referer" "$http_user_agent" '
        '"$gzip_ratio"';

    client_header_timeout   10m;
    client_body_timeout 10m;
    send_timeout        10m;

    connection_pool_size        256;
    client_header_buffer_size   1k;
    large_client_header_buffers 4 2k;
    request_pool_size       4k;

    gzip on;
    gzip_min_length 1100;
    gzip_buffers    4 8k;
    gzip_types  text/plain;

    output_buffers  1 32k;
    postpone_output 1460;

    sendfile    on;
    tcp_nopush  on;
    tcp_nodelay on;

    keepalive_timeout   75 20;

    ignore_invalid_headers  on;
    index index.html;

    server {
        listen 80;
        server_name localhost;
        location /static/  {
            root /srv/static/; 
        }
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov) {
            access_log   off;
            expires      30d; 
        }
        location / {
            # host and port to fastcgi server
            fastcgi_pass 127.0.0.1:8080;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_pass_header Authorization;
            fastcgi_intercept_errors off;
            fastcgi_param REMOTE_ADDR $remote_addr;
            }
        access_log  /var/log/nginx/localhost.access_log main;
        error_log   /var/log/nginx/localhost.error_log;
    }
}

Arquivos estáticos não estão sendo veiculados (nginx 404). Se eu olhar no log de acesso, parece que o nginx está procurando em / etc / nginx / html / static ... em vez de / srv / static / conforme especificado na configuração.

Não tenho ideia de por que está fazendo isso, qualquer ajuda seria muito apreciada.

    
por avalore 16.03.2012 / 19:51

2 respostas

13

Resposta curta : veja o último local na versão longa. Tecnicamente, a configuração descrita nessa página está errada. Veja o final da resposta por razões.

Resposta longa : você tem /etc/nginx... path em seus logs porque os pedidos de arquivos estáticos não correspondem à sua localização estática (o local regex leva precedente ) e você não especificou root para o bloco server em si.

Quando a sua solicitação corresponder à localização da regex, o nginx pesquisará os arquivos em /etc/nginx . Para corrigir isso, você pode querer adicionar a diretiva root diretamente dentro do bloco server , conforme descrito acima, ou sob cada localização não-proxy (o mesmo vale para o fastCGI também).

Também detectado: se você especificar root directive na localização, nginx pesquisará arquivos em $document_root/$location , por exemplo, em /srv/static/static , que é 99% não, você pode querer. Você pode usar a diretiva alias , mas a documentação do nginx prefere redefinir a diretiva root se isso for possível:

location /static {
    root /srv;
}

A diretiva alias funciona exatamente como você esperava, então você pode querer escrever isso:

location /static {
    alias /srv/static;
}

Quanto ao local da regex, você pode querer colocá-lo em /static location. Além disso, como haverá apenas arquivos estáticos, você poderá se livrar da localização do regex e a localização final ficará assim:

location /static {
    root /srv;
    access_log   off;
    expires      30d;
}

Por que a configuração descrita está errada e como corrigir isso

De acordo com os comandos que o usuário forneceu, ele gosta de ter a maioria dos componentes o mais nova possível rodando em um Linux parecido com o Debian. Mas ao invés de instalar tudo corretamente manualmente ou apenas usando o aptitude, ele começa a mixar e instalar softwares de pacotes também. Isso funcionará para alguma caixa de desenvolvimento, mas isso não é permitido para nenhuma produção. Então, aqui estão alguns pontos:

  1. Por favor, instale o software de uma maneira, preferencialmente dos pacotes. Se você precisar de uma versão de ponta, construa pacotes para eles (isso não é tão difícil;)) ou use algum ambiente para separá-los do sistema como virtualenv .
  2. Você não precisa adicionar manualmente o usuário e o grupo nginx. Servidores Web são executados a partir de www-data:www-data no Debian. Como sua configuração não pretende executar nenhum código dentro do contexto do servidor da web, adicionar mais usuários é inútil.
  3. O artigo sugere para redefinir todo o arquivo /etc/nginx/nginx.conf , o que é totalmente errado, especialmente em sistemas parecidos com o Debian. Em vez de fazer isso, você pode querer criar o arquivo sample_project em /etc/nginx/sites-available e vinculá-lo a /etc/nginx/sites-enabled para fazer o nginx anexar sua configuração ':
    # cd /etc/nginx/sites-enabled && ln -s ../sites-available/sample_project sample_project
  4. O arquivo sample_project , nesse caso, deve conter apenas o bloco server , nada mais.
  5. A maioria das diretivas (exceto log_format e talvez algumas outras) deve ter contexto de seu virtualhost e, portanto, deve ser colocada em server block no arquivo sample_project . Você não afetará o trabalho de outros serviços em execução neste servidor web. Você pode colocar a diretiva log_format em seu arquivo, mas fora de qualquer bloco e antes do próprio bloco server .
  6. Em vez de escrever todas as diretivas fastcgi_pass , deve-se escrever include fastcgi_params e apenas redefinir as que não estão corretas para a configuração atual.
  7. Para que seus arquivos de log sejam rotacionados automaticamente por logrotate, você deve nomeá-los para corresponder a *access.log ou *error.log curinga.

Se o arquivo de configuração do host funcional mínimo for /etc/nginx/sites-available/sample_project , poderá parecer:

server {
    listen 80;
    server_name myhostname.com;
    root /home/user/django/sample_project;

    location /static {
        root /srv;
        access_log   off;
        expires      30d;
    }

    location / {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:8080;
    }

    access_log      /var/log/nginx/sample_project.access.log combined;
    error_log       /var/log/nginx/sample_project.error.log warn;
}
    
por 16.03.2012 / 22:39
0

Você usa server_name localhost no bloco do servidor. Isso significa que o nginx só responderá por solicitações que tenham o campo de cabeçalho do host http 'localhost' ou possivelmente 127.0.0.1.

Solicitações com outros campos de host http irão para a localização padrão do nginx, que é - eu pensei - /usr/share/nginx/html .

Se você quiser ter certeza de que seu bloco de servidor aceita todas as solicitações recebidas, use server_name "" . Isto pode não ser o que você deseja para a configuração do django, no entanto.

    
por 16.03.2012 / 20:28

Tags