Nginx + Gunicorn POST request error - django

Im using nginx as a proxy for a django application that uses gunicorn, the problem is that at some point I receive a POST request from another site.
The problem seems to be that nginx does not redirect the POST request properly to the gunicorn daemon.
What can I do to fix this, what I need is to be able to send the POST request as it arrives to the gunicorn daemor for my django app to process it... thank you...
This is my nginx conf
server {
server_name www.rinconcolombia.com;
access_log /var/log/nginx/rinconcolombia.log;
location / {
ssi on;
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
autoindex on;
root /home/rincon/sites/rinconcolombia/checkouts/rinconcolombia/;
}
location /static/admin_media/ {
autoindex on;
root /home/rincon/sites/rinconcolombia/checkouts/rinconcolombia/;
}
}
server {
server_name www.rinconcolombia.com;
rewrite ^(.*) http://www.rinconcolombia.com$1;
}
UPDATE The app sending the POST is receiving a BAD REQUEST error... if I manually make a POST with resty or curl It does pass the post message to my server...

Your nginx configuration is slightly wrong as you're missing the fail_timeout bits. See here for the gunicorn/nginx example: https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf
Specifically lines 58 and 115.
If that doesn't help do you get anything in the nginx error.log?

Related

docker + nginx http requests not working in browsers

I have a AWS EC2 instance running Linux with docker containers running gunicorn/django and an nginx reverse proxy.
I don't want it to redirect to https at the moment.
When I try to reach the url by typing out http://url.com in the browser it seems to automatically change to https://url.com and gives me ERR_CONNECTION_REFUSED. The request doesn't show up at all in the nginx access_log.
But when I try to reach it with curl I get a normal response and it does show up in the nginx access_log.
I have ascertained that the django security middleware is not the cause as the HSTS options are disabled.
I've tried clearing the browser cache and deleting the domain from the chrome security policies.
nginx config:
upstream django_server {
server app:8001 fail_timeout=0;
}
server {
listen 80;
server_name url.com www.url.com;
client_max_body_size 4G;
charset utf-8;
keepalive_timeout 5;
location /static/ {
root /usr/share/nginx/sdev/;
expires 30d;
}
location / {
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;
proxy_pass http://django_server;
}
}
}
What am I overlooking?

Intermittent Bad Request (400) Spotify API callback using nginx + gunicorn + django

When I use nginx to serve my spotify django app with gunicorn socket handling communication, I would sometimes get Bad Request error during the user authentication callback. If gunicorn is configured as TCP with an ip and port, I don't experience the error, nor if I use django's manage.py runserver; user authenticates successfully. This intermittent issue seems to only occur when I'm using a socket connection. Checked nginx, gunicorn and django logs and didn't really get any info other than the 400 code.
Using tekore python library to access spotify's api.
Here's my nginx config:
upstream app_server {
server unix:/home/yg/Documents/projects/app/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name 192.168.0.26;
client_max_body_size 4G;
access_log /home/yg/Documents/projects/app/logs/nginx-access.log;
error_log /home/yg/Documents/projects/app/logs/nginx-error.log;
location /static/ {
alias /home/yg/Documents/projects/app/static/;
}
location /media/ {
alias /home/yg/Documents/projects/app/media/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_buffering off;
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/yg/Documents/projects/app/static/;
}
}
The issue wasn't related to nginx, turns out gunicorn doesn't support multiple workers with web socket. Changed my number of workers from 3 to 1.

Django nginx 502 bad gateway

I am learing nginx for django, i am running the server in locally with docker.
this is my django_nginix.conf file :
server {
listen 80;
listen [::]:80 default_server;
server_name musicaldd.com;
client_max_body_size 90M;
location /media/ {
root /home/pyking/cpd/musicaldd_back/storage/;
}
location /static/ {
root /home/pyking/cpd/musicaldd_back/storage/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://djangoapp:8000/;
}
}
When I run the server creating docker images and hit the URLs, it returns me 502-bed getaway timeout | nginix Can anyone tell me why this errors occuse, how can I fix this error
It may stupid question but this is very serious to me, coz, i am new on Nginx, it will really much be appreciated if you help me to fix this
If you are using uwsgi add this to your nginx.conf file based on your uwsgi params file location.
include /etc/nginx/uwsgi_params;
uwsgi_pass unix://tmp/uwsgi.sock;
uwsgi_param SCRIPT_NAME /;
If you are not i suggest use that. there is another option called gunicorn but uwsgi has better performance.

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

ERROR: Invalid HTTP_HOST header: '/webapps/../gunicorn.sock'

After I deployed my Django App last night I got tons of strange Emails saying:
ERROR: Invalid HTTP_HOST header: '/webapps/example_com/run/gunicorn.sock
I'm sure this is somehow related to the following nginx config:
upstream example_app_server {
server unix:/webapps/example_com/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
client_max_body_size 4G;
access_log /webapps/example_com/logs/nginx-access.log;
error_log /webapps/example_com/logs/nginx-error.log;
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://example_app_server;
break;
}
}
}
I found the answer to my my question in a django bug report.
proxy_set_header Host $http_host;
has to be replaced with:
proxy_set_header Host $host;
to make nginx pass the correct headers from that on instead of the gunicorn socket the requested page was in the django alerts.
This person explains a bit more what is going on based on this very same post. Here's his/her explanation:
...when a request is made to the server and the HTTP Host is empty, nginx sets the HTTP host to the gunicorn sock.
I can generate this error using curl:
curl -H "HOST:" MY_DOMAIN_NAME -0 -v
This sends a request without a HTTP Host. The -0 causes curl to use HTTP version 1.0. If you do not set this, the request will use HTTP version 1.1, which will cause the request to be rejected immediately and not generate the error.
The solution is to replace $http_host with $host (as pointed out on Stackoverflow). When HTTP Host is missing, $host will take on the value of the “server_name” directive. This is a valid domain name and is the one that should be used.
Add this in your settings.py file:
from django.http.request import HttpRequest
HttpRequest.get_host = HttpRequest._get_raw_host