简体   繁体   中英

Passing Static Content from Django/Gunicorn to Nginx

I've been playing around with Nginx & Gunicorn/Django for the past two days. Thought I'd share my troubles on here in hopes someone might have a potential solution

I have two separate machines. On one, I have a public facing box with nginx installed which acts as a reverse proxy for my other internal box with Django and Gunicorn installed.

When web requests come from the outside, Nginx simply acts as the middle man and forwards the request to Django/Gunicorn. Django/Gunicorn returns a response to Nginx. Nginx then takes that response and forwards back to where the web request came from. It's a pretty neat set up because Nginx can handle slow clients and take the hit in the case of a DDOS attack. Your actual application server is safe from any sort of damage :)

Although my application doesn't serve actual static content (pictures, videos etc ...). I would still like to pass static content from Gunicorn/Django to Nginx. Currently when I access the Django admin, it's just plain text with no graphics or images. It really sucks. I did however notice that when I accessed the Gunicorn/Django server directly, all the images for the Django admin showed up. It took me a while to understand what was happening here, and I realized that the static content wasn't being passed.

Here is my current Django urls.py configuration:

from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings 
from django.views.decorators.csrf import csrf_exempt


admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'django.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),
    url(r'^admin/', include(admin.site.urls)),

) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

This automatically finds the Django admin files and serves them to me through Gunicorn. I don't know how but it works. My debug settings is set to True so I don't know if that has anything to do with it.

My nginx conf looks like this:

worker_processes 1;

events {

    worker_connections 1024;

}

http {

    sendfile on;

    gzip              on;
    gzip_http_version 1.0;
    gzip_proxied      any;
    gzip_min_length   1000;
    gzip_disable      "MSIE [1-6]\.";
    gzip_types        text/plain text/xml text/css
                      text/comma-separated-values
                      text/javascript
                      application/x-javascript
                      application/atom+xml;

    # Configuration containing list of application servers
    upstream app_servers {

        server 10.101.010.111:8000;
        # server 127.0.0.1:8081;
        # ..
        # .

    }

    # I just added this in so that it will redirect all requests to HTTPs
    server {
        listen 80;
        server_name *.mydomain.com;
        rewrite ^/(.*) https://*.mydomain.com/$1 permanent;
    }

    # Configuration for Nginx
    server {

        # Running port
        listen 443;
        ssl on;
        server_name *.mydomain.com;

        ### SSL log files ###
        #access_log      logs/ssl-access.log;
        #error_log       logs/ssl-error.log;

        ### SSL cert files ###
        ssl_certificate      ssl/server.crt;
        ssl_certificate_key  ssl/server.key;

        ### Add SSL specific settings here ###


        ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        keepalive_timeout    15;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;

        # Settings to serve static files
        location ^~ /static/  {

            # Example:
            # root /full/path/to/application/static/file/dir;
            root /app/static/;
        }
        # Serve a static file (ex. favico)
        # outside /static directory
        location = /favico.ico  {

            root /app/favico.ico;

        }

        # Proxy connections to the application servers
        # app_servers
        location / {

            proxy_pass         http://app_servers;
            proxy_redirect     off;
            proxy_set_header   Accept-Encoding "";
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
            proxy_set_header   X-Forwarded-Proto $scheme;
            add_header         Front-End-Https on;
        }
    }
}

How can I pass static content from Django/Gunicorn to Nginx?

Looking forward to hearing your suggestions! I'm a self taught noob so any help would be extremely appreciated!

If you tell nginx to recognize the URI /static/, it will serve all files under that directory. In your mysite.conf:

location /static/ {
        alias /path/to/your/static/;
}

Edit: I'm going to try to explain why this works. Originally, Django is managing all your URLs. When it receives a request for a specific URL, it generates the appropriate response. However, when accessing something like an image, the initial response contains something like an <img> tag, which includes a source. The client then sends back a request to this source URL and asks for the image. The important part here is that the image is not served with the page initially. The other key is that nginx sees all requests first, and only passes to Django when it has to. If you tell nginx to recognize requests to /static/, you are telling it to intercept and answer all requests to this URI. Therefore, it will answer requests for static files without even passing to Gunicorn or Django. I'm new to this too, so this may not be completely accurate, but it's my best shot at an explanation!

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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