Digital Ocean, Django and Nginx not finding all static files - django

I have tried a lot of different things but all of the solutions I found are not helping.
I putting my corporate site on a digitalocean site on ubuntu 16.04 by following the digitalocean directions (which have worked well before) but it is only serving some of the static files.
Here are the links to the images.
<h3>Here is the image that doesn't load</h3>
<img src="http://206.189.161.104/static/images/frac_stack_1.jpg" alt="Image that doesn't load">
<h3>Here is the image that does load in the same folder</h3>
<img src="http://206.189.161.104/static/images/coil_pic.jpg" alt="Image that doesn't load" style="width:200px;height:200px;>
Here is my nginx config:
server {
listen 80;
server_name 206.189.161.104;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
root /home/dmckim/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/dmckim/myproject/myproject.sock;
}
}
I tried removing the trailing slash off the static (as shown above). I also tried changing root to alias and adding the static folder to the path but I had the same results.
Here is the code from my settings.py file:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
'/home/dmckim/myproject/static/',
'/home/dmckim/myproject/static/images/',
)
I also tried clearing collectstatic before collectingstatic again and I always run these commands after and make sure my browser cache is cleared.
sudo systemctl restart gunicorn
sudo nginx -t && sudo systemctl restart nginx
My permission on the files are -rw-rw-r--, for the image that does load and the one that doesn't load. I also tried a lot of ways to change permissions (I don't really understand them but they were suggested in other posts). I even destoyed the server and started from scratch to make sure I didn't mess anything up with the permissions.
I don't see anything wrong with the nginx process logs or the access logs but the error logs show the following:
2018/05/31 13:04:19 [error] 11481#11481: *22 open()
"/home/dmckim/myproject/static/images/frac_stack_1.jpg" failed (2: No such
file or directory), client: 12.184.4.50, server: 206.189.161.104, request:
"GET /static/images/frac_stack_1.jpg HTTP/1.1", host: "206.189.161.104",
referrer: "http://206.189.161.104/frac-stacks/"
The gunicorn logs show a 404 for the images that won't load.
Here is the www-data group uid=33(www-data) gid=33(www-data) groups=33(www-data)
Here is my group uid=1000(dmckim) gid=1000(dmckim) groups=1000(dmckim),27(sudo)

The file names are case sensitive. Your image is named "http://206.189.161.104/static/images/frac_stack_1.JPG" not "http://206.189.161.104/static/images/frac_stack_1.jpg".
<h3>Here is the image that loads</h3>
<img src="http://206.189.161.104/static/images/frac_stack_1.JPG" alt="Image that doesn't load" style="width:200px;height:200px;">
<h3>Here is the other image that does load in the same folder</h3>
<img src="http://206.189.161.104/static/images/coil_pic.jpg" alt="Image that doesn't load" style="width:200px;height:200px;>
Note that your results may differ when running this locally. Windows isn't case sensitive, Linux is. See this question for details

Related

Correctly serving manifest.json via Django's gunicorn

I have a Django web app that utilizes an nginx reverse proxy with a gunicorn application server (upstream).
My nginx logs are filling up with errors like these: 2020/03/03 22:51:57 [error] 9605#9605: *162393 upstream sent too big header while reading response header from upstream, client: 168.155.46.104, server: example.com, request: "GET /static/img/favicons/manifest.json HTTP/2.0", upstream: "http://unix:/home/ubuntu/app/myproj/gunicorn.sock:/static/img/favicons/manifest.json", host: "example.com", referrer: "https://example.com/signup/create-pass/new/6d756265726e2d3131/18/"
I'm assuming gunicorn was unable to serve manifest.json.
This shouldn't have happened. I've created manifest.json and placed it in the relevant location. Using the Favicon checker at https://realfavicongenerator.net/ shows me this error:
The Web App Manifest at https://example/com/static/img/favicons/site.webmanifest cannot be downloaded. If I hit that url directly in the brower, I end up seeing a 502 Bad Gateway error.
How can I fix this?
I figured out the error.
Files placed in the /static/ folder in my project are supposed to be served directly via nginx. But the json file in question wasn't included in nginx conf in a manner that allowed it to be served by the web server.
Once I fixed that (see below), the manifest file was directly served by nginx (and gunicorn never came in the loop). Problem solved!
This is what I added to nginx's virtual host file to solve the issue: Notice this includes the json extension:
location ~* \.(?:ico|css|js|gif|jpg|jpeg|png|svg|woff|ttf|eot|json)$ {
root /home/ubuntu/app/my_proj;
expires 120d;
access_log off;
error_log off;
}

How to associate only a subdomain to my Django App on Digital Ocean?

We already have a website called X.com. Now I am building a Django App on a Digital ocean Droplet. I am able to access it using the IP-address.
But we want to have it called reporting.X.com for sharing it with our users.
On my domain providers, I already added an A record like the below
Host- reporting
Type - A
Content - <ip-address> of digital ocean droplet
However I keep getting the following message when I try to access reporting.X.com.
What should I do?
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.
Okay I have resolved the issue. So I will answer this for future reference of other people.
You need to check 2 important places.
/etc/nginx/sites-enabled/<your_project>
If you want your django app with just the subdomain, your project file in sites-enabled should look like below.
server {
listen 80;
server_name <ip-address> .X.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/<user>/<project>;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/<user>/<project>.sock;
}
The dot in front of X.com is not a typo. This basically says any sub domain for X.com.
settings.py file in Django App
You have to set ALLOWED_HOSTS this way.
ALLOWED_HOSTS = ['ip-address', '.X.com']
Again X.com is preceded with a dot.
In the question, I already mentioned that I created an A record with following details.
Host- reporting
Type - A
Content - <ip-address> of digital ocean droplet
After this, restart your nginx server.
sudo systemctl restart nginx
Now, theoretically it should work. But if it doesn't (as it didn't for me), you have to shutdown and restart your droplet.
sudo shutdown -r now
My Django app started to work after this activity.
Hope it helps.

Gunicorn does not show Django static files

I've seen this question asked before but none of the responses have helped.
I'm trying to deploy my Python3/Django project to AWS with gunicorn + nginx. The project name is vicver, and when I try to run
$ gunicorn --bind 0.0.0.0:8000 vicver.wsgi
I can see my site on the AWS public IP port 8000 but without any js/css or images. When I do the same with the runserver command it works fine.
My settings.py contains the following paths:
STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [ os.path.join(BASE_DIR,'vicver/static') ]
And here's a screenshot of the terminal
https://imgur.com/a/KhgcXeT
It works when you run runserver command because you're in development mode. But when you want to deploy your application to production env, you should use some of these options to serve static files Deploying static files
Normally I use Nginx to serve static files, and create a reverse proxy to proxy other requests into the app which served by Gunicorn. You can take a look on this Deploying django application to serve your app by using Gunicorn too.
You can not serve your static and media file in the production mode(Debug=False). The best way to serve statics and media with this structure is by using Nginx.
First, you need to collect your statics using the following command:
python manage.py collectstatic
Then you need to edit your "nginx.conf" file using the following codes. Be careful to replace "/usr/src/app/" with your project path.
server {
listen 80 backlog=2048;
location = /favicon.ico { access_log off; log_not_found off;}
location /static/ {
alias /usr/src/app/vicver/static/;
}
location /media/ {
alias /usr/src/app/vicver/media/;
}
.
.
.
}

How do I deploy Django app to (AWS) domain name?

I've only been working with Django for a few weeks, and just learned deployment. I have an AWS EC2 Instance, which I'm able to deploy my Django website/app to (i.e., if I go to the IP address in my browser, I'm able to access my website). However, I can't figure out how to deploy that same website to my domain name, which is registered on AWS.
I followed AWS's documentation (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-ec2-instance.html), and https://cachecheck.opendns.com/ shows that my domain name routes to my EC2 instance. However, when I go to my domain name in my browser, it shows a 400 Bad Request. Is there something else I need to do when I setup nginx or gunicorn? I've tried replacing the {{yourEC2.public.ip}} in the nginx code to be my domain name instead of the IP address.
I haven't been able to find any other resources online regarding deployment to domain names, specifically with AWS.
This is what I have for deploying to the EC2 instance:
settings.py:
DEBUG = False
ALLOWED_HOSTS = ['{{yourEC2.public.ip}}']
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
(venv) ubuntu#54.162.31.253:~myRepoName$ python manage.py collectstatic
gunicorn
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/{{repoName}}
ExecStart=/home/ubuntu/{{repoName}}/venv/bin/gunicorn --workers 3 --bind
unix:/home/ubuntu/{{repoName}}/{{projectName}}.sock
{{projectName}}.wsgi:application
[Install]
WantedBy=multi-user.target
nginx:
server {
listen 80;
server_name {{yourEC2.public.ip}};
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/{{myRepoName}};
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/{{myRepoName}}/{{projectName}}.sock;
}
}
I had this exact same problem, and actually found your various posts also seeking solutions. Funny how we both had the exact same issue in such a similar window of time.
I did three things:
First, I updated my ALLOWED_HOSTS just as Selcuk noted:
ALLOWED_HOSTS = ['12.345.67.890', 'sub.domain.com', 'www.sub.domain.com']
Then, I also edited the server_name setting in my nginx configuration:
server_name 12.345.67.890 sub.domain.com www.sub.domain.com;
Lastly, I restarted nginx and rebooted the machine to make sure it all worked:
sudo service nginx restart
sudo reboot
After this, I was able to load my domain and the application would load. I know you already found your solution, but wanted to formalize this, as I found your question on StackOverflow and hopefully others will too so they may be spared!
You should set ALLOWED_HOSTS to your hostname(s), such as ['example.com', 'www.example.com']:
A list of strings representing the host/domain names that this Django site can serve. This is a security measure to prevent HTTP Host header attacks, which are possible even under many seemingly-safe web server configurations.

Django project deployment: cannot load static files

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;
...