Django project deployment: cannot load static files - django

I'm deploying a Django project using:
virtualenv
nginx
gunicorn
following this tutorial: https://www.digitalocean.com/community/tutorials/how-to-deploy-a-local-django-app-to-a-vps
My configuration
django settings
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATIC_URL = '/static/'
/etc/nginx/sites-available/esmart2
GNU nano 2.0.9 File: /etc/nginx/sites-available/esmart2
server {
server_name 192.168.30.17;
access_log off;
location /static/ {
alias /new_esmart/esmart2/static/;
}
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
Running
(esmart_env) [root#eprssrv09 esmart2]# /new_esmart/esmart_env/bin/gunicorn --bind 192.168.30.17:8001 esmart2.wsgi:application
My Django project is running but:
Not Found: /static/admin/css/login.css
Any advice?
UPDATE 1
I think that nginx settings are been avoided:
deleting any reference in 'sites-enabled' folder, django project runs and the problem concerning static files remain.
UPDATE 2
if in Django settings debug=True I get
Not Found: /static/admin/css/base.css
Not Found: /static/admin/css/login.css
Not Found: /static/admin/css/base.css

It seems I solved BUT I don't think is the better solution. I mean, it's a good solution depending on the project requirements: mine allows using this solution.
install package
pip install whitenoise
on wsgi.py I added:
from whitenoise.django import DjangoWhiteNoise
application = get_wsgi_application()
application = DjangoWhiteNoise(application)
This way nginx site conf is ignored (but I think they had already ignored!)
Django WhiteNoise documentation
With a couple of lines of config WhiteNoise allows your web app to
serve its own static files, making it a self-contained unit that can
be deployed anywhere without relying on nginx, Amazon S3 or any other
external service. (Especially useful on Heroku, OpenShift and other
PaaS providers.)
It’s designed to work nicely with a CDN for high-traffic sites so you
don’t have to sacrifice performance to benefit from simplicity.
WhiteNoise works with any WSGI-compatible app but has some special
auto-configuration features for Django.
WhiteNoise takes care of best-practices for you, for instance:
Serving compressed content (gzip and Brotli formats, handling
Accept-Encoding and Vary headers correctly) Setting far-future cache
headers on content which won’t change Worried that serving static
files with Python is horribly inefficient? Still think you should be
using Amazon S3? Have a look at the Infrequently Asked Questions.

It looks to me like the issue is two-fold:
It looks like you may have an error in your nginx config. Is new_esmart/ really in your root directory/ or is it somewhere like /home/sam/new_esmart/? If it is not in your root directory, make sure to provide the complete path.
It looks like your STATIC_ROOT will point to path/to/new_esmart/static/ rather than /new_esmart/esmart2/static/. Keep in mind that STATIC_ROOT is the place where your static files will be copied to when you run collectstatic not the place you personally place static files when creating them initially.
So what you probably need to do is confirm that you really want your static files collected to /actual/path/to/new_esmart/static/ and then use that same path in your nginx config.
Also, as discussed in the comments, you could try adding listen 8001; to your nginx config:
server {
listen 8001;
server_name 192.168.30.17;
access_log off;
...

Related

Nginx static files 404 with django swagger rest api

I have Django rest API application and swagger for that is working fine locally. I am trying to configure it using containers and deploy it on ECS.
Now when I build and run the container the application works fine (I mean the swagger UI is appearing). When I attach the application load balancer to it, on the browser it is giving me 404 files not found for js and CSS files.
Here is the console output from the web browser.
Here is my Nginx config file
# nginx.default
add_header X-Content-Type-Options nosniff;
include /etc/nginx/mime.types;
add_header X-XSS-Protection "1; mode=block";
server {
listen 8020;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8010;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
root /home/app/codebase;
}
}
THe path of static folder inside docker container is /home/app/codebase/static/
Also added the following lines in the Django Settings.py file.
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Not sure what am I missing. Any leads will be appreciated.
I have looked into these questions. The problem is something similar but not sure what I'm missing.
Posting the solution in case anyone still facing the same kind of issue.
I provisioned all the resources using IaC (Cloud Formation) so while provisioning Load Balancer I created the one target group but at that time the ECS services were not created, so I created a dummy target group that drops the traffic and was not routing the traffic to any service.
And in ALB's path-based routing, the last route (which the traffic uses when the request does not find any route) was directing traffic to a dummy target group.
As soon as I changed the target group everything works like a charm.
Working Fine
Pro Tip:
Always use any of the target groups from your application in the last ALB rule.

Bad Gateway 502 Error with Django, Gunicorn and Nginx

I am trying to run project on Django with Gunicorn and Nginx. On DigitalOcean OneClick install image my project works fine with no virtualenv and with global Django installation. But when I created virtual environment for different Django version I couldn't get it to work. So kindly someone please provide me some help with the multi site hosting on Ubuntu using virtual environment. Follwing is my Gunicorn settings for virtual environment:
description "Gunicorn daemon for Django project"
start on (local-filesystems and net-device-up IFACE=eth0)
stop on runlevel [!12345]
# If the process quits unexpectadly trigger a respawn
respawn
setuid django
setgid django
chdir /home/django
exec gunicorn \
--name=myproject2\
--pythonpath=myproject2\
--bind=127.0.0.1:9500 \
--config /etc/gunicorn.d/gunicorn.py \
myproject2.wsgi:application
My Nginx settings for the second project are:
upstream ashyanaa_server {
server 127.0.0.1:9500 fail_timeout=0;
}
server {
listen 80;
listen [::]:80;
root /home/django/myproject2;
index index.html index.htm;
client_max_body_size 4G;
server_name www.myproject2.com;
keepalive_timeout 5;
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|woff|ttf)$ {
expires 365d;
}
# Your Django project's media files - amend as required
location /media {
alias /home/django/myproject2/media/;
}
# your Django project's static files - amend as required
location static/static-only {
alias /home/django/myproject2/static-only/;
}
# Django static images
location /static/myproject2/images {
alias /home/django/myproject2/static-only/images/;
}
# Proxy the static assests for the Django Admin panel
location /static/admin {
alias /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://myproject2_server;
}
Only thing different in my first project settings from the second are that I am using virtual environment for the second project and obviously I had to use different port for new project.
'Bad Gateway' indicates that Nginx is having trouble connecting the the Gunicorn process.
Double check that the service that starts Gunicorn (the one defined by the upstart script you posted) is actually running
What happens when you do curl http://127.0.0.1:9500/? Do you get a response from Gunicorn?
This is due to lack of understanding about Nginx. I added www.mydomain.com in Nginx but I have habit of typing domain name without www in browser. I simply added "mydomain.com" and "www.mydomain.com". So now both working without error. For others to follow if you have all the settings correct and still getting 502 that means the address you are looking for is not listed in Nginx. It could be one of the reason. Thanks for help though guys.

Lazily serving Django static content with NGINX

Let's say I've got Django code rooted in /var/my_app. I've got a MEDIA_ROOT configured at /var/my_app/files, and MEDIA_URL is /var/my_app/files at /files. Serving these files through UWSGI (or gunicorn, etc.) works fine.
Now I am trying to use the NGINX try_files directive to serve them without hitting UWSGI. Here's what I've got:
location /files/* {
try_files /var/my_app$uri $uri;
}
Wherein my understanding is that if I am attempting to access $hostname/files/photos/thumbs/file.jpg, the above location matches, $uri is /files/photos/thumbs/file.jpg, NGINX tests /var/my_app/files/photos/thumbs/file.jpg and should return the file if it exists.
Instead, when I access that URI, I see the request passed through to UWSGI in the UWSGI log, even though the file exists at /var/my_app/files/photos/thumbs/file.jpg. What am I doing wrong? I read the docs on try_files, but clearly I am misunderstanding something.
For reference, here is the Django location block:
location / {
include uwsgi_params;
uwsgi_param UWSGI_SETENV DATABASE_URL=[redacted]
uwsgi_pass 127.0.0.1:3034;
}
Added Context
This configuration is targeted at lazily serving Django-generated thumbnails (using easy-thumbnails) if they do not yet exist.

Nginx is not serving Django static files

I just configured my first django server for a very basic django-website. I'm using Django 1.4 and Nginx 1.0.14 with supervisor and gunicorn.
The problem is that Nginx is not serving the static files as suposed, but I don't know the why because is my first time using it.
This is the path where really lives my static files:
/home/cristian/envs/santalupe.com/santalupe/santalupe/static
And this is the setting I've in my nginx config file:
# Django admin media.
location /media/ {
autoindex on;
alias /home/cristian/envs/santalupe.com/lib/python2.7/site-packages/django/contrib/admin/static/;
}
# Site media
location /static/ {
autoindex on;
alias /home/cristian/envs/santalupe.com/santalupe/santalupe/static/;
}
Please let me know what I need to do in this case because I have not idea about the real problem.
You aren't serving the admin media from Nginx, just normal media. Try something like:
location /admin/media/ {
# this changes depending on your python version
root /home/cristian/envs/santalupe.com/lib/python2.7/site-packages/django/contrib;
}
Note how there's no trailing slash and the path ends at contrib. I'm using almost exactly this code successfully in production.
Maybe manage.py collectstatic on server help you?
Here is good description on right solution https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-production

Running Multiple Sites with Django's Sites Framework through Gunicorn/Nginx

I have a Django based CMS that uses Django's sites framework and Nginx/Apache/mod_wsgi virtual hosts to run a number of websites on different domains. We're assessing other options for a Django stack and have the CMS running with a single site on a new server with Nginx proxying to Gunicorn (gunicorn_django, specifically).
Although this works great for a single site, I'm not sure how to configure Gunicorn for multiple sites. The problem is that with Apache/mod_wsgi, we could set the DJANGO_SETTINGS_MODULE for mod_wsgi to the appropriate site's settings.py
import os, sys
def inflight(filename):
"""
Calculate absolute path to the folder containing "myfile.wsgi", then
append to the PYTHONPATH.
"""
ROOT = ('/').join(os.path.abspath(os.path.dirname(filename)).split('/')[0:-1])
sys.path.append(ROOT)
sys.path.append(os.path.join(ROOT, 'website'))
sys.stdout = sys.stderr
# Each website should have a settings file: /www/mysite.com/website/settings.py
os.environ['DJANGO_SETTINGS_MODULE'] = 'website.settings'
import django.core.handlers.wsgi
return django.core.handlers.wsgi.WSGIHandler()
At the moment I'm thinking that I have to have a different instance of Gunicorn for each virtual host site we run but that seems overkill for the traffic we get to most of our sites.
Does anyone run Gunicorn with Django's sites framework and can give a hint to how it's configured?
I had the same problem and stumbled upon this question in search of the same answer.
I know the question is old and you've probably figured it out by now, but since it might be useful for someone else, here's how I solved it:
You do need to run separate gunicorn processes to make django sites framework work because you can only point a gunicorn instance at one settings.py file. If you're sites don't get much traffic, I'd only create 1 or 2 gunicorn workers per site. (I know, still probably overkill).
Ideally you would want to manage these different processes with something like supervisord to make it easier to manage starting/stoping/restarting your different sites, but I couldn't get it working.
First, start up your gunicorn servers on local host at different ports using the command line. Ex:
gunicorn_django -w 2 -b 127.0.0.1:1000 /path/to/my/django/project/site1_settings.py --daemon
gunicorn_django -w 2 -b 127.0.0.1:1001 /path/to/my/django/project/site2_settings.py --daemon
You now have 2 django sites running on localhost at ports 1000 and 1001 (you can use whatever ports suite you).
Now you need to create two separate nginx server configuration files to point each domain name at it's respective django site.
Ex:
server {
listen 80;
server_name website1.com;
client_max_body_size 4G;
keepalive_timeout 4;
location /media {
root /path/to/my/django/project/media; #this servers your static files
}
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://127.0.0.1:1000; #point to the django site already running on local host
break;
}
}
#add in any additional nginx configuration such as support for 500 errors or proxy apache to server php files etc.
}
Then create a duplicate of the nginx configuration for your 2nd site, but change the server name and the proxy_pass to the values for site 2.
Make sure your server configuration files are included in the main nginx.conf file.
Reload nginx and you should be good to go.
If anyone has an easier/better way to go about this please post it.