簡體   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