120 votes

Comment faire en sorte que Django serve des fichiers statiques avec Gunicorn ?

Je veux exécuter mon projet django sous gunicorn sur localhost. J'ai installé et intégré gunicorn. Lorsque je lance :

python manage.py run_gunicorn

Il fonctionne mais il n'y a pas de fichiers statiques (css et js).

J'ai désactivé debug et template_debug dans settings.py (en les rendant faux), mais c'est toujours pareil. Est-ce qu'il me manque quelque chose ?

J'appelle les statiques comme ça :

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

224voto

rantanplan Points 3497

Lorsque dans développement et lorsque vous utilisez un autre serveur pour le développement local ajoutez ceci à votre url.py

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

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

urlpatterns += staticfiles_urlpatterns()

Plus d'informations ici

Lorsque dans production tu ne dois jamais, jamais mettre gunicorn devant. A la place, tu utilises un serveur comme nginx qui distribue les requêtes à un pool de travailleurs gunicorn et sert également les fichiers statiques.

Véase ici

40voto

Ciro Santilli Points 3341

Whitenoise

Post v4.0

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

L'option d'intégration WSGI pour Django (qui impliquait d'éditer wsgi.py) a été supprimée. À la place, vous devriez ajouter WhiteNoise à votre liste d'intergiciels dans settings.py et supprimer toute référence à WhiteNoise dans wsgi.py. Consultez la documentation pour plus de détails. (L'intégration WSGI pure est toujours disponible pour les applications non-Django).

Pré v4.0

Heroku recommande cette méthode à : https://devcenter.heroku.com/articles/django-assets :

Votre application servira désormais des ressources statiques directement à partir de Gunicorn en production. Cela conviendra parfaitement à la plupart des applications, mais les applications de haut niveau peuvent envisager d'utiliser un CDN avec Django-Storages.

Installer avec :

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)

Testé sur Django 1.9.

29voto

Hugo Points 3276

Je l'ai utilisé pour mon environnement de développement (qui utilise 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()

Et puis lancez gunicorn myapp.wsgi . Cela fonctionne similaire a Réponse de @rantanplan Cependant, il n'exécute pas d'intergiciel lorsqu'il exécute des fichiers statiques.

25voto

Ngure Nyaga Points 1645

Le gunicorn doit être utilisé pour servir l'"application" python elle-même, tandis que les fichiers statiques sont servis par un serveur de fichiers statiques (tel que Nginx).

Ceci est un extrait d'une de mes configurations :

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

Quelques notes :

  • La racine statique, la racine média, le préfixe du chemin des fichiers statiques et le préfixe du chemin des fichiers média sont définis dans votre fichier settings.py.
  • Une fois que nginx est configuré pour servir à partir du répertoire de contenu statique, vous devez exécuter "python manage.py collectstatic" dans la racine de votre projet afin que les fichiers statiques des différentes applications puissent être copiés dans le dossier statique.

En conclusion : bien qu'il soit possible de servir des fichiers statiques à partir de gunicorn (en activant une vue de service de fichiers statiques en débogage seulement), cela est considéré comme une mauvaise pratique en production.

14voto

Afin de servir des fichiers statiques, comme Jamie Hewland dit normalement on route toutes les demandes vers /static/ en utilisant Nginx

location /static/ {

    alias /path/to/static/files;

}

Nginx + Gunicorn + Django

En d'autres termes, et comme coreyward dit à propos de Gunicorn / Unicorn

n'a pas été conçue pour résoudre l'ensemble des problèmes liés au service fichiers aux clients

Le même raisonnement s'applique si vous considérez un autre serveur WSGI comme uWSGI au lieu de Gunicorn. Sur Documentation uWSGI

il est inefficace de servir des fichiers statiques via uWSGI. Au lieu de cela, servez-les directement depuis Nginx et contournez complètement uWSGI.


Le moyen le plus simple est de servir vos fichiers statiques avec Python en utilisant WhiteNoise qui est très facile à configurer (vous pouvez utiliser un CDN pour que la plupart des requêtes n'atteignent pas l'application Python). Comme Miguel de Matos dit vous n'avez qu'à

  1. Collecte statique

     python manage.py collectstatic
  2. Installation de whitenoise

     pip install whitenoise
  3. Ajoutez ce qui suit STATICFILES_STORAGE dans settings.py

     STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
  4. Ajoutez les éléments suivants à votre MIDDLEWARE dans settings.py (en tant que mracette note, "Selon la documentation de whitenoise, vous devriez placer le middleware après django.middleware.security.SecurityMiddleware ")

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X