Django | Static files served by nginx not used by Client - python

I have a django app, with the following settings for static files:
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [STATIC_DIR,]
STATIC_ROOT = '/opt/static/'
I am running django using the follwoing gunicorn command:
gunicorn evee.wsgi -b 0.0.0.0:8000.
I have configured nginx to serve the static files and ssl using the following conf:
server {
keepalive_timeout 5;
listen 443 ssl;
server_name api.home.com;
client_max_body_size 4G;
error_page 500 502 503 504 /500.html;
# path for static files
root /opt;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
proxy_set_header X-Forwarded-Proto $scheme;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://evee:8000;
}
}
Interesting part is that I am able to see the CSS in the client. For example, the request to https://secapi.ril.com/static/admin/css/base.css is successful and returns a 200 response. I can view all the static files at the URL mentioned, but django does not seem to use them. Have tried changing clients as well as private mode.
Am I doing something terribly wrong? This was working last time I checked.

Try adding static files path in your nginx config files as:
location /static/ {
alias /opt/static/;
}
Here mention complete path to your static folder. I guess in your case its /opt/static/

Here is how I solved this. Had to edit the nginx.conf file to configure an upstream instead of redirecting it to http directly and removed a few headers that were being set. No clue how different it is or why this works. The entire setup is running in Docker Swarm.
#### SECAPI #####
upstream app_server {
# for a TCP configuration
server evee:8000 fail_timeout=0;
}
server {
keepalive_timeout 5;
listen 443 ssl;
server_name api.home.com;
client_max_body_size 4G;
error_page 500 502 503 504 /500.html;
# path for static files
root /opt;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
}

Related

invalid parameter server_name in /etc/nginx/sites-enabled/django

I've deployed a Django application on DigitalOcean.
First off, when i try to secure this with https and ssl, I get this error.
when i run nginx -t :
nginx: [emerg] invalid parameter "server_name" in /etc/nginx/sites-enabled/django:12
nginx: configuration file /etc/nginx/nginx.conf test failed
upstream app_server {
server unix:/home/django/gunicorn.socket fail_timeout=0;
}
server {
#listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;
listen 443 ssl
server_name domain.com
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
root /usr/share/nginx/html;
index index.html index.htm;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# Your Django project's media files - amend as required
location /media {
alias path/to/media;
}
# your Django project's static files - amend as required
location /static {
alias path/to/static;
}
# Proxy the static assests for the Django Admin panel
location /static/admin {
alias path/to/staticadmin;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://app_server;
}
}
server {
listen 80;
server_name domain.com;
return 301 https://$host$request_uri;
}
Furthermore, I can access the website using the ip address but not the domain name registered.It results in a 400 bad request page.
Could this be an issue with the settings.py ?
for reference in settings.pyALLOWED_HOSTS=['*']. What list do I provide in the ip_addresses() function?
Are these two problems related?
using Django v1.10.5
You're missing semicolons on a bunch of lines, that's why nginx -t is failing.

django production deployment does not load static files

I've been trying for about a whole day to deploy Django's static files in production, but till now I had no luck, so I absolutely need community's help!
My nginx config is:
worker_processes 1;
user nobody nogroup;
pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;
events {
worker_connections 1024;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /tmp/nginx.access.log combined;
sendfile on;
upstream app_server {
server unix:/tmp/gunicorn.sock fail_timeout=0;
# For a TCP configuration:
# server 192.168.0.7:8000 fail_timeout=0;
}
server {
listen 80 default;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# path for static files
root /home/ubuntu/src/static;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/ubuntu/src/static;
}
}
}
and in my django settings.py file I've set the following:
STATIC_URL = '/static/'
STATICFILES_DIRS = ()
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
and of course I've run the collectstatic django command and the folder in path /home/ubuntu/src/static exists containing all appropriate files.
Still my deployment does not server any static file :/
Does anybody have any idea what might be wrong with my setup?
Thank you in advance
I used a great tutorial here for my setup. Hopefully this can help. One obvious change I can see is using location /static/ for static files and just forwarding location / straight to gunicorn (or uwsgi in my case)
Add static alias to server conf
location /static {
alias /home/ubuntu/src/static; # your Django project's static files - amend as required
}
Full configuration should be like
server {
listen 80 default;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# path for static files
# root /home/ubuntu/src/static;
location /static {
alias /home/ubuntu/src/static; # your Django project's static files - amend as required
}
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/ubuntu/src/static;
}
}
}

How to perform url rewrites for different flask apps on different locations on same nginx server with uwsgi?

I am facing the following probelm:
I have set up nginx to listen to two different upstream app servers running with uwsgi on different ports. The two applications use the same static files but depending on the nginx location the firstapplication or the secondapplication gets loaded:
server {
listen 80;
server_name localhost;
charset utf-8;
client_max_body_size 75M;
# Proxy connections to the application servers
# app_servers
location /firstapplication {
include /etc/nginx/mime.types;
proxy_pass http://app_servers_firstapplication/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
rewrite /?(?!/firstapplication)/(.+) /firstapplication/$1 last;
}
location /secondapplication {
include /etc/nginx/mime.types;
proxy_pass http://secondapplication/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
rewrite /?(?!/secondapplication)/(.+) /secondapplication/$1 last;
}
location ^~ /scripts/ {
alias /webapps/scripts/;
}
location ^~ /css/ {
alias /webapps/html/css/;
}
location ^~ /graphics/ {
alias /webapps/html/graphics/;
}
location ^~ /fonts/ {
alias /webapps/html/fonts/;
}
}
When I call mydomain/firstapplication or mydomain/secondapplication the initial page of the corresponding app gets loaded right.
But when the initial page of the app gets loaded and I click on a link in the app it is using the app's urls like /contact instead of /firstapplication/contact and therefore I geht a 404 error for every url I call in the application.
I wanted to solve this problem with location specific rewrites in nginx like this:
rewrite /?(?!/firstapplication)/(.+) /firstapplication/$1 last;
and
rewrite /?(?!/secondapplication)/(.+) /secondapplication/$1 last;
I used a negative lookbehind assertion to avoid a circular redirect when I load the page /fistapplication.
This rewrite regex should work I tested it in this online editor: http://regex101.com/r/yH7sP0/1
Unfortunately nginx does not redirect the application urls and they still lead to 404 errors.
Can I use nginx rewrite module to achieve my goal? Or what other approaches could I use to run two diffrent apps on the same nginx server?

Nginx, uwsgi and flask does not display the css file

I have set up uwsgi and nginx to serve a flask website that I'm working on but it refuses to display the css file even though it appears in the body of the page correctly and I can view it. It does not change the styling of the page.
I use the following nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript
application/x-javascript
application/atom+xml;
# Configuration containing list of application servers
upstream uwsgicluster {
server 127.0.0.1:8080;
# server 127.0.0.1:8081;
# ..
# .
}
# Configuration for Nginx
server {
# Running port
listen 80;
# Settings to by-pass for static files
location ^~ /static/ {
# Example:
# root /full/path/to/application/static/file/dir;
root /app/static/;
}
# Serve a static file (ex. favico) outside static dir.
location = /favico.ico {
root /app/favico.ico;
}
# Proxying connections to application servers
location / {
include uwsgi_params;
uwsgi_pass uwsgicluster;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}

Django SSL Redirect snippet modification, not working as expected

I'm using Nginx as webserver, with a reverse proxy to a gunicorn django server.
I tried using the SSLRedirect snippet from here:
http://djangosnippets.org/snippets/85/
Because this snippet would always return false from is_secure() with my setup, resulting in a redirect loop, I had to make some changes.
SSL works, but when I access http://domain.net/main it doesn't redirect to https://domain.net/main. Isn't it supposed to do that?
Below outlines the modification I made:
if 'HTTP_X_FORWARDED_PROTOCOL' in request.META:
return True
And in my nginx conf (I only need SSL, http not required):
server {
listen 8888;
server_name domain.net;
ssl on;
ssl_certificate /path/to/domain.pem;
ssl_certificate_key /path/to/domain.key;
# serve directly - analogous for static/staticfiles
location /media/ {
root /path/to/root;
}
location /static/ {
root /path/to/root;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://127.0.0.1:8881/;
# note this line
proxy_set_header X-Forwarded-Protocol https;
}
}
Just do it entirely with nginx. No need to involve Django at all:
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
server {
listen 443;
# The rest of your original server config here
}

Categories

Resources