47

I'm using apache+mod_wsgi for django.
And all css/js/images are served through nginx.
For some odd reason, when others/friends/colleagues try accessing the site, jquery/css is not getting loaded for them, hence the page looks jumbled up.

My html files use code like this -

<link rel="stylesheet" type="text/css" href="http://x.x.x.x:8000/css/custom.css"/>
<script type="text/javascript" src="http://1x.x.x.x:8000/js/custom.js"></script>

My nginx configuration in sites-available is like this -

    server {   
         listen   8000;   
         server_name  localhost;

         access_log  /var/log/nginx/aa8000.access.log;    
         error_log  /var/log/nginx/aa8000.error.log;    

           location / {   
               index  index.html index.htm;    
           }    

         location /static/ {    
            autoindex on;    
            root   /opt/aa/webroot/;    
         }    
     }   

There is a directory /opt/aa/webroot/static/ which have corresponding css & js directories.

The odd thing is that the pages show fine when I access them.
I have cleared my cache/etc, but the page loads fine for me, from various browsers.

Also, I don't see 404 any error in the nginx log files.

Any pointers would be great.

sikerbela
  • 388
  • 1
  • 4
  • 17
PlanetUnknown
  • 3,956
  • 4
  • 49
  • 67
  • I know it may be obvious but it wasnt for me, after you do the changes run: `sudo nginx -s reload` That should make it work, it did for me – Chuox Aug 26 '21 at 15:24

5 Answers5

94

I think using root in location block is incorrect. I use alias and it works fine, even without re-configuring django.

# django settings.py
MEDIA_URL = '/static/'

# nginx server config
server {   
    ...
    location /static {    
        autoindex on;    
        alias /opt/aa/webroot/;    
    }
}

Hope this makes things simpler.

miki725
  • 27,207
  • 17
  • 105
  • 121
  • 12
    Indeed, `alias` is the proper method to serve entire directories. – xyzman Apr 25 '12 at 12:27
  • 6
    Same works for me, because /static and /static/ are different locations and in second variant I always got permission error from nginx. – Dracontis Aug 17 '12 at 12:13
  • 2
    For anyone reading this. Nginx docs clearly state, that "When location matches the last part of the directive’s value it is better to use the root directive instead" http://nginx.org/en/docs/http/ngx_http_core_module.html#alias Also see this answer: http://serverfault.com/a/278359 – PF4Public Nov 22 '15 at 23:17
  • Awesome, thank you and I wish this was explained in a Passenger tutorial. It's taken me 4 days to find this information. Alias is the correct choice for me because the folder is called 'assets' not 'static', so you need to provide a completely different name not just a path. – Little Brain Dec 10 '18 at 16:15
  • In my case I have a trailing slash in the "location /static/ {}". Removing the trailing slash and using alias to the staticfiles path worked for me. It should be now "location /static { alias }" then reload/restart nginx. – Ronnie Beltran Jan 06 '21 at 03:52
18
  1. server_name must match hostname in link/script URLs. Either declare your configuration as default for this interface:port pair (listen 8000 default)
  2. Nginx must listen on the interface where your host's IP is bound (seems ok in your case)
Alexander Azarov
  • 12,971
  • 2
  • 50
  • 54
  • 3. URI of js/css and other static files should start with /static/ prefix in your html file, so that it can match to /static/ location block in your nginx conf. – Zubair Alam May 11 '19 at 09:02
14

I also struggled with this. However, following trick worked for me:

server {   
     listen   8000;   
     server_name  localhost;

     access_log  /var/log/nginx/aa8000.access.log;    
     error_log  /var/log/nginx/aa8000.error.log;    

       location / {   
           index  index.html index.htm;    
       }    

     location ^/static/ {    
        autoindex on;    
        root   /opt/aa/webroot/;    
     }    
 } 

I just marked static as a regex with ^ and nginx started serving static files. No modification on Django side was needed.

Shiv
  • 1,912
  • 1
  • 15
  • 21
5

MEDIA_URL shall not be used to serve the Static content like js etc. Django provides a separate STATIC_URL settings option that can be used.

So this can be changed as

<script type="text/javascript" src="{{STATIC_URL}}js/jquery-1.3.2.min.js"></script>

Also, its more standard to use staticfile app templatetag like this:

{% load static from staticfiles %}
<script type="text/javascript" src="{% static 'js/jquery-1.3.2.min.js' %}"></script>

Docs Here

umang agarwal
  • 344
  • 2
  • 4
4

Fim & Alexander - Thanks for the hints those helped.
Here is how I solved it for anyone stuck in the same boat -

settings.py -

>MEDIA_ROOT = ''    
MEDIA_URL = 'http://x.x.x.x:8000/static/'    

In my html -

<script type="text/javascript" src="{{MEDIA_URL}}js/jquery-1.3.2.min.js"></script>

In my views.py -

return render_to_response('templates/login-register.html', {},
                          context_instance=RequestContext(request));    

nginx inside the sites-available config file -

listen x.x.x.x:8000;    
server_name x.x.x.x.;

Restarted nginx
Restarted apache

istruble
  • 13,363
  • 2
  • 47
  • 52
PlanetUnknown
  • 3,956
  • 4
  • 49
  • 67
  • 1
    Unless you also have the "location /static" etc in your nginx conf Django will be serving the static files. Fine for testing and dev but not a good idea for production. – ostergaard Apr 10 '13 at 11:05