繁体   English   中英

如何让 Django 使用 Gunicorn 提供静态文件?

[英]How to make Django serve static files with Gunicorn?

我想在本地主机上的 gunicorn 下运行我的 django 项目。 我安装并集成了 gunicorn。 当我运行时:

python manage.py run_gunicorn

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

我在 settings.py 中禁用了 debug 和 template_debug(使它们为假),但它仍然是一样的。 我错过了什么吗?

我称静态为:

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

开发模式下以及使用其他服务器进行本地开发时,将其添加到您的 url.py

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

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

urlpatterns += staticfiles_urlpatterns()

更多信息在这里

生产中,您永远不会将 gunicorn 放在前面。 相反,您使用像 nginx 这样的服务器,它将请求分派到 gunicorn 工作人员池并提供静态文件。

这里

白噪声

发布 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 在生产中提供静态资产。 这对于大多数应用程序来说已经足够了,但是顶级应用程序可能想要探索使用带有 Django-Storages 的 CDN。

安装:

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 上测试。

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

这是我的配置之一的摘录:

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 提供静态文件(通过启用仅调试的静态文件服务视图),但这在生产中被认为是不好的做法。

我已经将它用于我的开发环境(使用 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 的答案类似,但是,它在运行静态文件时不运行任何中间件。

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

location /static/ {

    alias /path/to/static/files;

}

Nginx + Gunicorn + Django

换句话说,正如科里沃德所说的 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. 在 settings.py 中添加以下STATICFILES_STORAGE

     STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
  4. 在 settings.py 中将以下内容添加到您的MIDDLEWARE (如mracette 所述,“根据 whitenoise 文档,您应该将中间件放在django.middleware.security.SecurityMiddleware之后”)

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

从 Django 1.3 开始,有 django/conf/urls/static.py 在 DEBUG 模式下处理静态文件:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

阅读更多https://docs.djangoproject.com/en/2.0/howto/static-files/#serving-static-files-during-development

如果您使用的是 Apache/Gunicorn,那么这就是我的设置方式。

  1. 在您的 Django 根目录(使用manage.py )中,创建目录mkdir -p django_static/static

  2. 在您的项目settings.py设置以下内容:

DEBUG = False
INSTALLED_APPS = [..., 'django.contrib.staticfiles', ...]
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, "django_static", "static")
  1. 运行python manage.py collectstatic 这会将静态内容输出到django_static/static

  2. 使用gunicorn your_project_name.wsgi启动你的gunicorn服务器(加上选项)

  3. 假设你有默认的全局 Apache 设置,你需要创建一个从/var/www到你的静态目录的软链接: sudo ln -s /path/to/your_django_project/django_static /var/www/your_django_project_static

  4. 对于您希望指向 Django 应用程序的域www.example.com ,请在 apache 中配置以下虚拟主机,以便将提交到https://www.example.com的所有请求代理到127.0.0.1:8000上,除了www.example.com/static/路由(在这种情况下,为来自django_static的此类请求提供文件):

<VirtualHost *:443>
    ServerName www.example.com
    DocumentRoot /var/www/your_django_project_static
    <Location "/">
        ProxyPreserveHost On
        ProxyPass http://127.0.0.1:8000/
        ProxyPassReverse http://127.0.0.1:8000/
    </Location>
    <Location "/static/">
        ProxyPass "!"
    </Location>
</VirtualHost>

瞧!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM