0

I having difficulty serving static files with Django 1.10, uWSGI and Nginx.

I have an index.html file, which contains CDN's.

The Django documentation, which is here says to "transfer the static files to the storage provider or CDN." What does that mean, "transfer to the CDN"? Isn't the CDN where you get files from?

settings.py contains,

STATIC_URL = '/static/'

STATIC_ROOT = 'nonAppBoundStaticDirectory'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

Running

$ python manage.py collectstatic

does this place all CDN's in my directory 'nonAppBoundStaticDirectory'?

If so then how do i use that in the template?

Excerpt from index.html

  <!-- Bootstrap -->
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css">

Excerpy from /etc/nginx/nginx.conf

server {
    # the port your site will be served on
    listen  80;
    # the domain name it will serve for
    server_name example.com;   # substitute your machine's IP address or FQDN
    charset     utf-8;

    #Max upload size
    client_max_body_size 75M;   # adjust to taste

    # Django media
    location /media  {
                alias /home/ofey/djangoForum/fileuploader/uploaded_files;      # your Django project's media files
    }

        location /static {
                alias /home/ofey/djangoForum/noAppBoundStaticDirectory;     # your Django project's static files
        }
........

Thanks,

Shane G
  • 3,129
  • 10
  • 43
  • 85
  • 1
    For larger websites it's a good idea to also serve your custom css, js etc from a cdn, just like you do with the third party bootstrap assets. But in your case, you don't use a cdn to manage your own static assets. So the django storage backend just copies the files to somewhere else on the application server, where nginx can serve them directly. – Håken Lid Dec 04 '16 at 15:14
  • Hi thanks, so are all the CDN files copied to the STAIC_ROOT when I run collectstatic ? – Shane G Dec 04 '16 at 15:21
  • Sorry I should check myself, rather than ask. – Shane G Dec 04 '16 at 15:22
  • Tried that just now and no it doesn't. – Shane G Dec 04 '16 at 15:25
  • Depends what you mean by "CDN files". Django's staticfiles framework will not read every html snippet and look for links to external cdn files. Only files in your project's static files directories are copied. – Håken Lid Dec 04 '16 at 15:26
  • 1
    So django will not pull any files from CDNs to save them locally. But if you use a CDN `STATICFILE_STORAGE`, django's `collectstatic` will upload your _own_ custom assets from `STATICFILE_DIRS` to a remote CDN server. For example Amazon Cloudfront. You have to configure the staticfile backend using valid api keys for this to work, though. In addition, the template tag `{% static %}` will create an url pointing to where your assets are served from the CDN. – Håken Lid Dec 04 '16 at 15:32
  • When you hardcode a `` in your html `head` to the bootstrap css hosted a cdn, that completely bypasses django. That's fine. There's ususally no need to pass those files through django's static files framework. – Håken Lid Dec 04 '16 at 15:34
  • Then it would be better in this case to use CDN's hardcoded in the link. That doesn't seem to be working and I wonder could it have anything to do with my iptables? – Shane G Dec 04 '16 at 15:54
  • 1
    In that case, you need to explain what is not working and how you expect it to work. [mcve] – Håken Lid Dec 04 '16 at 16:02
  • I had previously taken the content of the CDN's and moved them into the static file. But now they are normal CDN's in the link as above in the question and they work. What doesn't work now are the static files i.e. css, js etc. As this is now a different question about static files and not CDN I should possibly post a new question. – Shane G Dec 04 '16 at 16:17
  • For example I can't get this to work – Shane G Dec 04 '16 at 16:19
  • After running collectstatic, all static files are in /home/ofey/djangoForum/noAppBoundStaticDirectory How do i get Django to look there? Or should that directory be outside Django and on the nginx server? If so is there anywhere particular it should so? Thanks – Shane G Dec 04 '16 at 16:22
  • 1
    You would typically copy static files to a directory where they are served by nginx. So your `STATIC_ROOT` value should be the absolute path (starting with `/`) of that directory. The same as you use in the nginx configuration. If nginx cannot serve those files, make sure that the nginx process has read permission to that directory. – Håken Lid Dec 04 '16 at 16:27
  • Into django's settings.py I put STATIC_ROOT = '/staticQqiFiles' – Shane G Dec 04 '16 at 16:36
  • and into /etc/nginx/nginx.conf I put location /static { alias /staticQqiFiles; } – Shane G Dec 04 '16 at 16:37
  • I created that new directory at / of the system. So it is in there with boot dev etc home lib.... Also I restarted everything again but still not reading the css. see it at qqiresources.com By the way www.qqiresources.com doesn't work. But that's another days work :) – Shane G Dec 04 '16 at 16:37
  • 2
    Reading this question I get the impression you are confused what a CDN is. It's a service, that you pay for, that takes your files, stores them on its own servers, and serves them for you. You can't have an index.html that "contains CDNs": that makes no sense at all. – Daniel Roseman Dec 04 '16 at 17:07
  • Did you do `django-admin collectstatic` after changing the directory name? And also make sure that the django process has read/write access to the directory and nginx has read access. After you do collectstatic, check that the folder contains the files. Also check the expected url for a asset file in your browser to see if nginx is serving the file. – Håken Lid Dec 04 '16 at 17:17
  • @DanielRoseman You are correct I am confused. I understood that instead of having files locally on your server they would be on a remote server somewhere else. The advantage being that if they are updated, this will benefit everyone getting these files from the remote server. But obviously that's not correct. – Shane G Dec 04 '16 at 17:57

2 Answers2

1

It might be just a spelling mistake. In your settings.py you have an extra n in the directory name.

STATIC_ROOT = 'nonAppBoundStaticDirectory'

In your nginx config, you have a different spelling.

location /static {
    alias /home/ofey/djangoForum/noAppBoundStaticDirectory; 

Make sure that the path point to the exact same directory. It's can be a good idea to use absolute paths in both cases.

Håken Lid
  • 22,318
  • 9
  • 52
  • 67
  • In index.html I have In settings.py STATIC_ROOT = '/home/ofey/djangoForum/nonAppBoundStaticDirectory' And in nginx.conf I have location /static { alias /home/ofey/djangoForum/nonAppBoundStaticDirectory; } These are all absolute paths, but still not working. – Shane G Dec 04 '16 at 18:39
  • And this file exists /home/ofey/djangoForum/nonAppBoundStaticDirectory/assets/css/main.min.css I can't see why it isn't working. – Shane G Dec 04 '16 at 18:40
  • 1
    I visited your site. The requests to the css files return a "403 forbidden" response. This probably means that nginx does not have read permission to the staticfiles directory. Make sure that the nginx user has read permission both to the files, and also execute permission to all parent directories. See this question for details. http://stackoverflow.com/questions/6795350/nginx-403-forbidden-for-all-files – Håken Lid Dec 04 '16 at 19:21
  • That link to the question was very helpful thank you. I added a user to nginx.conf and recursively changed the permissions to 775 in nonAddBoundStaticDirectory Alot more of the css is being used but it still isn't correct. I need to examine the index.html more closely. Site now looks like this qqiresources.com and should looks like this https://cloud.githubusercontent.com/assets/17167992/16212578/a920aa5e-3740-11e6-99be-e3dc7f0134d5.png – Shane G Dec 04 '16 at 22:28
0
  1. Working in development server

If you are working in development server- remove STATIC_ROOT from settings.py. Your settings.py should now look like this:

    STATIC_URL = '/static/'

    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static'),
    ]
  1. Production

If you are working in production- remove STATICFILES_DIRS from settings.py. Your settings.py should now look like this:

    STATIC_URL = '/static/'

    STATIC_ROOT = 'nonAppBoundStaticDirectory'

And don't forget to run:

    python manage.py collectstatic
Pranava Mohan
  • 533
  • 2
  • 8
  • 18