Django only serves index page, 404 on all others - django

I have a simple django app im trying to throw up on digital ocean. I have configured NGINX to proxy my port and serve the static files. However, when I click on any link to go to another page, it 404s on me. It only serves the index page correctly, everything else is a 404.
If any of you back-end wizards have any other do's/don't's that i'm currently doing, feel free to add those in your response.
I'm very new to NGINX so please dumb it down :) Thanks.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
location /static {
alias /home/rchampin/ryan_the_developer_django/static;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
}

You've explicitly instructed nginx to return 404 on non file requests. You don't need to do this. Django can manage Error 404s. You only need to add a 404.html in your template directory and Django will have this page shown when there's a 404 Not Found Error.
Plus you don't need to hard code your index page, what's the point of using Django. Michał Karzyński has a very good documentation on how to setup Nginx with Django:
Setting up Django with Nginx, Gunicorn, virtualenv, supervisor and PostgreSQL

Related

Configure Nginx to serve Angular front end, Django Rest Framework backend on same server?

My site's frontend is built with Angular 7, and the back end is built with Django Rest Framework. It's all running via docker-compose, and I'm trying to serve the entire site through NGINX.
The basic premise of my configuration is this:
If the request includes a url with /api/ or /admin/ in it, allow gunicorn to handle the request.
If the url is anything else, send it to the root index.html so that Angular can handle the routing.
The root url / should serve my pre-compiled javascript via the index.html.
With the following Nginx config, I can visit all of the Angular routes. I can visit the admin page and my browsable API. However, when I go to /admin or the browsable API, all of the static files return a 404 error.
Do you see the issue? Thanks!
# urls.py
urlpatterns = [
re_path(r'^favicon\.ico$', favicon_view),
path('api/v1/', include('api.urls'), name='api'),
path('admin/', admin.site.urls),
]
# nginx.conf
upstream my_app {
server django:8000;
}
server {
listen 80;
location /staticfiles/ {
alias /usr/src/app/staticfiles/;
}
location ~ (api|admin) {
proxy_pass http://my_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location / {
root /usr/src/app/staticfiles/;
try_files $uri $uri/ /index.html;
}
}
Your configs are saying that everything available from /api/ or /admin/ are provided by the proxy to my_app. So, you may either ensure that the static files used by those endpoints are available through Django Rest Framework, OR tell NGINX to always try the static files first, then fall back to the my_app proxy.
The first option will involve setting STATIC_ROOT, STATIC_URL, STATICFILES_STORAGE, etc per the Django documentation on static files (link goes to current dev version).
The other option involves collecting the assets used by /api/ and /admin/ in the same location as your Angular assets, and altering your NGINX configuration to look something like this:
# nginx.conf
upstream my_app {
server django:8000;
}
server {
listen 80;
location /staticfiles/ {
alias /usr/src/app/staticfiles/;
}
location / {
root /usr/src/app/staticfiles/;
try_files $uri $uri/ index.html;
location /drf {
proxy_pass http://my_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
}
This basically says try to look up everything in your Angular staticfiles directory, if it's not found, try looking it up in your DRF application.

How to serve React app AND Django blog from Nginx?

I'm using nginx to serve a React app from my domain root / and a Django blog app from /blog. I'm also using nginx to redirect all http to https.
The problem is some weird behaviour... If I navigate to the blog with a clear cache, it shows the blog. If I then navigate to the index page it shows the react app. All good so far. But then, if I return to /blog it continues to show the react app, not the blog! I think the problem involves caching, but I'm not sure where.
I am not using react-router, so I'm not sure how the urls could get redirected on the client side.
Here is my nginx config:
server {
listen 80;
server_name mydomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name mydomain.com;
root /production_build;
location /static/ {
root /var/www/mysite;
}
location /blog {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://upstream_django_server;
}
location /cms {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://upstream_django_server;
}
location / {
try_files $uri /index.html;
}
}
You should disable the service worker in react, as it is interfering with your /blog url and returning its own response the next time.
Since you are mixing 2 apps here, you don't want to take a risk of having something which is difficult to get rid of.
Service workers can be sometimes very nasty because of caching responses

How to deploy django on VPS with external subdomain.?

Good day.
I have a web app that I have developed using django. I tested fine on my local, and I'm happy with how it works.
However I'm facing an issue bringing it online I used those two guides to reach my deployment:
https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04
and
http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/
However my page is giving me a forbidden page.
I suspect my issue is with the way I'm handling the subdomain. So the site . has been developed using php, and I have worked on my part with django and been provided with a subdomain which is member.domain.com, So I'm deploying it on the VPS and have to make it use the subdomain.
This is how my allowed hosts looks in the settings.py
ALLOWED_HOSTS = ['member.domain.com']
and
in my nginx:
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/home/path/project/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name member.domain.com;
client_max_body_size 4G;
access_log /home/path/project/logs/nginx-access.log;
error_log /home/path/project/logs/nginx-error.log;
location /static/ {
alias /home/path/project/src/static/;
}
location /media/ {
alias /home/path/project/src/media/;
}
location / {
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
# proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
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;
# set "proxy_buffering off" *only* for Rainbows! when doing
# Comet/long-poll stuff. It's also safe to set if you're
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
# Error pages
error_page 502 503 504 /500.html;
location = /500.html {
root /home/path/project/src/static/;
}
}
I'm not sure what I am doing wrong.
I will appreciate any help
To respond to 'example.com' and any subdomains, start the domain with a dot
ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
I didn't even try how to run django on subdomains, but from article link you shared, you missed some configuration in your settings.py
ALLOWED_HOSTS = ['member.domain.com']
Changed
ALLOWED_HOSTS = ['.domain.com']
Hope this will solve your problem

Configure Django App as nginx location

I am trying to deploy a Django app along a static html website. The general www.example.com will provide the basic website. The URI /app should then proxy to a Gunicorn WSGI server. The nginx configuration in sites-enabled looks as follows:
upstream gunicorn {
server 127.0.0.1:8000;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/website;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://gunicorn;
}
}
I am getting a 404 error when trying www.example.com/app. It seems the URI gets messed up somehow. The complete URL that is created is http://www.example.com/accounts/login/?next=/app/
Setting up the App alone exactly following this tutorial http://hackedexistence.com/project/raspi/django-on-raspberry-pi.html does work.
Is the setup I am aiming at even possible? And if yes, where is my misunderstanding of the location concept?
You need to set the SCRIPT_NAME header in your location directive.
proxy_set_header SCRIPT_NAME /app;
See this blog post for an example.

How to configure nginx for a rails single page application?

I am trying to configure nginx to render a Rails 4 single page application. The index page exists within a Rails template index.html.erb. Javascript and CSS are both on a CDN. The current configuration allows the page to load, and I can navigate the entire site. The issue comes when I try to reload the page or attempt to navigate to a page via the address bar: mysite.com/about. What am I missing? I have experience with single page apps but usually the page is external to Rails.
I am using:
Rails 4
Unicorn v4.3.1
Openresty 1.5.11.1
Nginx configuration:
upstream rails_server {
server unix:/var/www/mysite.org/api/shared/tmp/.unicorn.mysite-org.sock fail_timeout=0;
}
server {
listen 80 default_server deferred; # for Linux
server_name staging.mysite.org;
client_max_body_size 5m;
keepalive_timeout 5;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
# proxy_cookie_domain api.local.mysite.org local.mysite.org;
proxy_pass http://rails_server;
}
location ~* /application.*\.css$ {
return 301 $scheme://css.mysite.org$request_uri;
}
location ~* /application.*\.js$ {
return 301 $scheme://js.mysite.org$request_uri;
}
}