Django 3 Static Files and NGINX

Tags: NGINX, Django, troubleshooting

Published May 2, 2020, 4:40 p.m. by Morgan

As mentioned in my first post, I followed the book, Django 3 by Example, to make this blog. As also mentioned, it was not deployed as the root website directory as generally intended. All I wanted to do was put it in another directory and make /blog on the URL direct to it. I figured, "I'm new to this, but how hard could it be?" Spoiler alert: when you're doing all the administration yourself... very. (TL;DR at bottom if you want to skip the thrilling adventure)

I guess the more precise name for what I did was deploying an application same server and as a subdirectory——for others getting started, a subdirectory is like, www.example.com/subdirectory, which is different from a subdomain, as in www.example.com vs co.example.com; the more you know! Not knowing this terminology was problem #1, since so many of the posts on stackoverflow etc were about development, while I was having an issue with the deployment phase. Speaking of problems, I should probably explain what the big deal was.

Django applications use static files like CSS, and pointing both the app and the server to a non-conventional location turned out to be the main challenge. Playing with the urls.py in the main project directory solved the first issue of getting the page URLs to load correctly, but left the lack of CSS unresolved. I couldn't for the life of me figure out why the CSS wouldn't load. I looked in the Django docs (including static files, serving them in deployment, and the various settings); read through the relevant parts of, Nginx HTTP Server (2018); and pored over every hit on Google. The logs looked fine, more or less, and everything seemed to be configured correctly. The answer finally came from a "clue" in an answer on stackexchange, after seeing someone on stackoverflow mention that they troubleshot their issue using the inspect element browser tool. That second one might have been a no-brainer for someone more experienced, but for someone who was fixated on, "why won't this server work?!" it was the push I needed to put the pieces together.

Loading the bland html page with the console up, I could now see that the request for the static files was happening as it should, but just returning a 404. The lightbulb moment was when I could see the actual URL of the request and put together how everything was supposed to work. In a bout of luck, I'd forgotten my earlier troubleshooting of setting the CSS <link=> in the 'base.html' (the base template for the Django app pages) header to an absolute path, removing the Django {% static %} shortcut in the hope that it would bypass the static settings. I say luck, because seeing that big absolute path attached to the end of upusual.com made it abundantly clear that the request was happening through the Django blog html template. That is, it was being read, but the server, not Django, was trying to do the static request. Since I knew NGINX was doing the handling, I replaced the absolute path with the static Django shortcut in base.html, and was rewarded by the expected URL request... but still a 404. I now knew the issue had to be in the NGINX configuration file for the site, since that was how NGINX knew where to look for the request.

I'd felt a bit silly getting a whole book on NGINX, but that, combined with the aforementioned answer on stackexchange, was what led to the ultimate solution. I'm not sure if the person giving out the, "clue," as they put it, to the original question in that thread intended it as such, but after reading that, I took a closer look at the book section on regex for location blocks. Turns out that regex affects how NGINX prioritizes location blocks. When you use expressions, you can affect the prioritization of the location blocks because specificity gets preference. As near as I can tell, NGINX was prioritizing looking up requests for /static/ in the website root folder (confirmed when I dropped a copy of the static folder in there), and effectively ignoring the location block for /static/. Simply changing it to ^~ /static was enough to bump it up on the priority list, and boom: the site has bushleague CSS from the intended directory.

As an ending note, I did a lot of reading on the static files before realizing it was a server/pathing problem, and many explanations were far too technical (including the docs), so here is my understanding of the mandatory static files options in the settings.py file for Django during deployment:

STATICFILES_DIRS: where the original static files for each application are. These are the ones you edit when you want to change anything. You need to specify the absolute path to them, and can list them as tuples if you want to add a namespace for them, like [ ("namespace0", "/abs/path/to/project/app0/static"), ("namespace1", "/abs/path/to/project/app1/static"), ].

STATIC_ROOT: where the server goes to look for the static files to serve. Running python /abs/path/to/project/manage.py collectstatic copies your static files indicated in the above STATICFILES_DIRS and places them here. It's usually set to os.path.join(BASE_DIR, 'static/').

STATIC_URL: how the request is sent to the server. That is, if I put it at /other/static/, the server request should look like example.com/appname/other/static/ in the element inspector. Usually set to '/static/' and left untouched.

If you're ever unsure if one of these might be an issue, you can always add print('\nBASE_DIR: ',BASE_DIR,'\nSTATIC_ROOT: ',STATIC_ROOT, <or whatever>) at the end of the settings.py file and run it to see how the actual paths look (\n linebreaks are there for readability). The other STATIC options were not used in this endeavor, so I don't know what those

TL;DR NGINX was not prioritizing location blocks like I expected it to. Adding an arbitrary regex so it read location ^~ /static {alias ... made it prioritize the desired pathing to the alias directory.

Hopefully that helps anyone else who got similarly stuck. I do not claim to be an expert, just someone who had to learn by fixing, so corrections are welcome.

Similar posts

There are no similar posts yet.

2 comments

Comment 1 by Unjurge June 14, 2022, 1:19 p.m.

Difference Entre Cialis Et Generique https://newfasttadalafil.com/ - Cialis Zktfvf Rezept Viagra Torte Qvaejx Infection viruses most common viral gastroenteritis followed by bacteria then parasites b. <a href=https://newfasttadalafil.com/>Cialis</a> Headaches Headaches are common during pregnancy. Cefjvj Viagra Generic Retailer https://newfasttadalafil.com/ - comprar cialis online

Comment 2 by Plonsok Nov. 29, 2022, 7:33 p.m.

To evaluate the impact of including non breast cancer deaths in low risk patient populations, simulations were performed similar to those shown in Figure 1 Data Supplement <a href=http://bestcialis20mg.com/>cialis for daily use</a> Immunotherapy has become a standard of care for the treatment of many solid tumors

Add a new comment