如何使Django通过Gunicorn提供静态文件?


77

我想在localhost的gunicorn下运行django项目。我安装并集成了Gunicorn。当我跑步时:

python manage.py run_gunicorn

它可以工作,但是没有任何静态文件(css和js)

我在settings.py中禁用了debug和template_debug(将它们设置为false),但是仍然相同。我想念什么吗?

我称静态为:

{{ STATIC_URL }}css/etc....

Answers:


174

开发模式下以及将其他服务器用于本地开发时,请将其添加到url.py

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# ... the rest of your URLconf goes here ...

urlpatterns += staticfiles_urlpatterns()

更多信息在这里

生产中,您永远都不会将金枪鱼放在前面。取而代之的是,您使用像nginx这样的服务器,该服务器将请求分派给Gunicorn工作者池,并提供静态文件。

这里


当我重新启用debug和template_debug时,它开始正常工作。将这些行放入urls.py没关系。但现在我看不到我的自定义404和500错误页面。在生产中; 我应该进行False Debug和template_debug吗?
alix 2012年

@drTerminal我更新了答案,并包括了我引用的django链接的特定措辞。仅当DEBUG = False时才显示自定义404/500页面。请阅读具体链接,我认为它将回答您的大多数问题。
rantanplan 2012年

尽管我使用Django 1.6,这对我还是有用的。在docs.djangoproject.com/zh-CN/1.4/howto/static-files/…中,urlpattern对于1.6有不同的用法,但对我来说没有结果。因此,我成功地使用了1.4解决方案。
2014年

1
@binki啊!您让我搜索了:P所以...由于我记忆犹新,您实际上可以做到,所以我进行了搜索。如果您下载此pdf文件media.readthedocs.org/pdf/django/1.4.X/django.pdf,这是我的答案所指的过时版本,则您会发现应用服务器是否可以不能,因为Django为您做到了。当然,它的效率很低,但是仍然可行。不知道是否有可能,如果可以,怎么办。
rantanplan '16

1
嗯,看来django.views.static.serve现代文档中仍然会存在这种情况。但是从1.4文档中基本上没有改变,但警告相同:“此视图未用于生产用途,应仅用作开发辅助工具”。措辞不强。因此,使用纯django甚至可以记录下来,都是可行的,只是我猜它是“不受支持的”用法。仅该serve功能始终可用,但static辅助功能会在生产中自动禁用。
宾基

31

白噪声

后v4.0

http://whitenoise.evans.io/en/stable/changelog.html#v4-0

Django的WSGI集成选项(涉及编辑wsgi.py)已被删除。相反,您应该将WhiteNoise添加到settings.py的中间件列表中,并从wsgi.py中删除对WhiteNoise的任何引用。有关更多详细信息,请参见文档。(纯WSGI集成仍可用于非Django应用。)

v4.0之前的版本

Heroku在以下网址推荐此方法:https : //devcenter.heroku.com/articles/django-assets :

现在,您的应用程序将直接在生产中从Gunicorn提供静态资产。对于大多数应用程序而言,这将是完全足够的,但是顶级应用程序可能想要使用CDN和Django-Storages进行探索。

安装方式:

pip install whitenoise
pip freeze > requirements.txt

wsgi.py

import os
from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "free_books.settings")
application = get_wsgi_application()
application = DjangoWhiteNoise(application)

在Django 1.9上测试。


2
因此,这再次说明WSGI应用程序正在提供静态文件。不是金枪鱼。
宾基

1
pip freeze > requirements.txt将覆盖以前的要求,我建议pip freeze | grep whitenoise >> requirements.txt
Marco Lavagnino

3
自白噪声版本4.0起不推荐使用上述说明。 whitenoise.evans.io/en/stable/changelog.html#v4-0
Fuchida

15

gunicorn应该用于为python“应用程序”本身提供服务,而静态文件由静态文件服务器(例如Nginx)提供服务。

这里有一个很好的指南:http : //honza.ca/2011/05/deploying-django-with-nginx-and-gunicorn

这是我的配置之一的节选:

upstream app_server_djangoapp {
    server localhost:8000 fail_timeout=0;
}

server {
    listen < server port goes here >;
    server_name < server name goes here >;

    access_log  /var/log/nginx/guni-access.log;
    error_log  /var/log/nginx/guni-error.log info;

    keepalive_timeout 5;

    root < application root directory goes here >;

    location /static {    
        autoindex on;    
        alias < static folder directory goes here >;    
    }

    location /media {
       autoindex on;
       alias < user uploaded media file directory goes here >;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        if (!-f $request_filename) {
            proxy_pass http://app_server_djangoapp;
            break;
        }
    }
}

一些注意事项:

  • 静态根目录,媒体根目录,静态文件路径前缀和媒体文件路径前缀在您的settings.py中设置
  • 设置好nginx以便从静态内容目录提供服务后,需要在项目根目录中运行“ python manage.py collectstatic”,以便可以将各种应用程序中的静态文件复制到静态文件夹中

最后:虽然可以从gunicorn提供静态文件(通过启用仅调试的静态文件提供视图),但这在生产中被认为是不好的做法。


1
是的我知道。我将在生产中在nginx下使用它。我只是在生产前在本地主机中进行测试。
alix 2012年

当您说“虽然可以从gunicorn提供静态文件”时,您实际上是在说“如果unicorn委派请求的WSGI应用程序提供静态文件,那么gunicorn将间接提供静态文件”?
宾基

7

我已经在我的开发环境(使用gunicorn)中使用了它:

from django.conf import settings
from django.contrib.staticfiles.handlers import StaticFilesHandler
from django.core.wsgi import get_wsgi_application


if settings.DEBUG:
    application = StaticFilesHandler(get_wsgi_application())
else:
    application = get_wsgi_application()

然后运行gunicorn myapp.wsgi。此作品相似@ rantanplan的答案,但是,在运行静态文件,当它不运行任何中间件。


3

为了提供静态文件,正如Jamie Hewland所说,通常一个使用Nginx将所有请求路由到/ static /

location /statis/ {

    alias /path/to/static/files;

}

Nginx + Gunicorn + Django

换句话说,正如Coreyward所说,关于Gunicorn / Unicorn

并非旨在解决向客户提供文件方面的一系列问题

如果您考虑使用其他WSGI服务器(例如uWSGI)而不是Gunicorn,则适用相同的推理方法。在uWSGI文档中

通过uWSGI服务静态文件效率低下。相反,直接从Nginx提供服务并完全绕过uWSGI


更简单的方法是使用WhiteNoise库通过Python提供静态文件,该库非常易于设置(您可能希望使用CDN,以便大多数请求不会到达Python应用程序)。正如Miguel de Matos所说,您只需要

  1. 收集静态

    python manage.py collectstatic
    
  2. 安装白噪声

    pip install whitenoise
    
  3. STATICFILES_STORAGE在settings.py中添加以下内容

    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
    
  4. 将以下内容添加到您MIDDLEWARE的settings.py中

    `MIDDLEWARE = [
      'whitenoise.middleware.WhiteNoiseMiddleware',
      'django.middleware.security.SecurityMiddleware',
      ...
    ]
    

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.