nginx+django提供静态文件

nginx+django提供静态文件

我已按照 django wiki 中的说明设置 django 和 nginx(https://code.djangoproject.com/wiki/DjangoAndNginx) 并按如下方式设置 nginx(更改了一些名称以适合我的设置)。

    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;
    }
}

静态文件未被提供 (nginx 404)。如果我查看访问日志,似乎 nginx 正在查找 /etc/nginx/html/static... 而不是配置中指定的 /srv/static/。

我不知道它为什么会这样做,如能得到任何帮助我将非常感激。

答案1

简短回答:请参阅长版本中的最后一个位置。从技术上讲,该页面中描述的设置是错误的。请参阅答案的末尾以了解原因。

长答案:您的日志中可能有/etc/nginx...路径,因为对静态文件的请求与您的静态位置不匹配(正则表达式位置优先) 您还没有rootserver块本身指定。

当您的请求与正则表达式位置匹配时,nginx 将搜索下的文件/etc/nginx。要解决此问题,您可能需要如上所述root直接在块内添加指令,或在每个非代理位置下添加指令(fastCGI 也是如此)。server

还发现:如果你root在 location 下指定指令,nginx 将在 下搜索文件$document_root/$location,例如 中的/srv/static/static文件 99% 可能不是你想要的。你可以使用alias指令,但nginx 文档root如果可能的话,倾向于重新定义指令:

location /static {
    root /srv;
}

alias指令的工作方式与您预期的一样,因此您可能希望这样写:

location /static {
    alias /srv/static;
}

至于正则表达式位置,您可能希望将其放在/static位置内。此外,由于只有静态文件,您可以删除正则表达式位置,最终位置将如下所示:

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

为什么描述的设置是错误的以及如何修复它

根据用户提供的命令,他希望在类似 Debian 的 Linux 上运行大多数尽可能新鲜的组件。但他没有手动正确安装所有内容或仅使用 aptitude,而是开始混合和安装软件包中的软件。这适用于某些开发箱,但不适合任何生产。因此,这里有一些要点:

  1. 请以一种方式安装软件,最好是从软件包安装。如果您需要前沿技术,请为它们构建软件包(这并不难 ;) )或使用某些环境将其与系统分开,例如virtualenv
  2. 您无需手动添加 nginx 用户和组。Web 服务器在www-data:www-dataDebian 中运行。由于您的设置不打算在 Web 服务器上下文中运行任何代码,因此添加更多用户是没有意义的。
  3. 这篇文章建议重新定义整个/etc/nginx/nginx.conf文件,这是完全错误的,尤其是在类似 Debian 的系统上。与其这样做,你可能想创建sample_project文件/etc/nginx/sites-available并将其链接到/etc/nginx/sites-enabled以使 nginx 附加你的配置:
    # cd /etc/nginx/sites-enabled && ln -s ../sites-available/sample_project sample_project
  4. 在这种情况下,文件sample_project应该只包含server块本身,仅此而已。
  5. 大多数指令(log_format可能除了某些其他指令)都应具有虚拟主机的上下文,因此应将其放置server在文件中的块下sample_project。这不会影响在此 Web 服务器上运行的其他服务的工作。您可以将log_format指令放置在文件中,但应放置在任何块之外且位于server块本身之前。
  6. 我们不应该编写所有fastcgi_pass指令,而应该编写include fastcgi_params并仅重新定义那些不符合当前设置的指令。
  7. 要让您的日志文件通过 logrotate 自动轮换,您应该将它们命名为匹配*access.log*error.log通配符。

给出最小的工作主机配置文件/etc/nginx/sites-available/sample_project可能如下所示:

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;
}

答案2

server_name localhost在服务器块中使用。这意味着 nginx 将仅响应具有 http 主机头字段“localhost”或可能是 127.0.0.1 的请求。

带有其他 http 主机字段的请求将进入 nginx 的默认位置,也就是 - 我认为 - /usr/share/nginx/html

如果您想确保您的服务器块接受所有传入请求,请使用server_name ""。不过,这可能不是您想要的 django 配置。

相关内容