i have a react frontend imported inside a django backend. communication between the two is done through django-rest-framework. on the react's side, fetching is done through relative paths therefore in my package.json i have added the line:
"proxy": "http://127.0.0.1:8000",
django is hosting react-app locally without problems when i run: python3 manage.py runserver.
on the remote i am trying to use nginx with gunicorn to deploy this app on aws ubuntu instance and run into the problem:
first, i'm running python3 manage.py collectstatic
later, i'm pointing nginx to that static_files for the index.html
success! nginx serves react static files
use gunicorn myapp.wsgi -b 127.0.0.1:8000 to run django
problem! nginx served react files do not fetch anything. fetch does not call for this local path but instead calls public ip of aws instance. also, i cannot simulate get/post requests to the django backend because i think nginx "covers" django's gunicorn generated paths.
please tell how can i connect nginx-served react frontedn to gunicorn run django
my nginx sites-enabled/example
server {
listen 80 default_server;
listen [::]:80 default_server;
root /home/ubuntu/fandigger/frontend/build/;
server_name public_ip_without_port;
location / {
try_files $uri $uri/ =404;
}
}
I have a ruby file index.rb that contains puts "this is to show in nginx landing page".
My nginx landing location is /usr/share/nginx/html and my configuration is
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.rb index.html index.htm;
server_name localhost;
}
How do I print those lines without ruby on rails or python django? Do I need to build my code?
Nginx cannot run the index.rb script, in part because it does not have an embedded ruby (or python) interpreter. What you might want to do is to run your script through a uWSGI app. As documented here, for ruby, you need to create an app.ru script with a call entry point (which will just load your index.rb script). It is then run via:
uwsgi --socket 127.0.0.1:3031 --rack app.ru
Your nginx server can then access the uWSGI process with the following configuration:
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
uwsgi_modifier1 7;
}
I am stuck with setting the https with django on aws with nginx and gunicorn.
my configuration is:
server {
listen 80;
listen 443 ssl;
server_name logitech.enterpriselist.com;
rewrite ^ https://logitech.enterpriselist.com$request_uri? permanent;
root /home/ubuntu/git/elist/static/;
#` ssl on;
ssl_certificate /etc/ssl/elist.crt;
ssl_certificate_key /etc/ssl/elist.key;
location / {
# proxy_pass http://logitech.enterpriselist.com/;
}
location /static/ {
alias /home/ubuntu/git/elist/static/;
}
}
It is working fine with http with port 8001:
gunicorn configs.wsgi:application --bind 172.31.14.102:8001`
and not with domain
http://logitech.enterpriselist.com:8001/.
But I also want to run the things with the default port, but when I run
gunicorn configs.wsgi:application --bind 172.31.14.102:80
it says address already in use!
Also with https when I open http://logitech.enterpriselist.com/, it goes to https://logitech.enterpriselist.com/ but it says website have redirect loop so I need help in sorting this.
You haven't got anything to tell nginx it should be proxying requests to gunicorn. In particular, you need a proxy_pass directive and an upstream section.
Also, you don't want to run gunicorn on port 80, since that is what nginx is already bound to. That's what the proxy is for.
The gunicorn deployment docs have an example nginx configuration which works fine.
Hi I am new with nginx server, and I have uploaded my index.py file at /var/www/pyth/index.py ...
I am a little bit confused because in my local I can run freely
python index.py and access http://127.0.0.1:8080
I was wondering how can I do that in nginx, I have run python index.py but I can't access to mysite.com:8080
this is my config in /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;`
#root /usr/share/nginx/html;
#index index.php index.py index.html index.htm;
root /var/www/mysite.com;
index index.php index.py index.html index.htm;
# Make site accessible from http://localhost/
server_name mysite.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
# Only for nginx-naxsi used with nginx-naxsi-ui : process denied reques$
#location /RequestDenied {
# proxy_pass http://127.0.0.1:8080;
#}
#error_page 404 /404.html;
...
does anyone has an idea about my case? any help will be appreciated.. thanks in advance
You should set up either a uwsgi (or similar), or a proxy_pass in nginx.
The option with UWSGI is better because it'll use the protocol designed for working with web-servers; though it's a bit harder to set up than just proxying everything via nginx.
proxy_pass
web.py has a web-server just for the development purposes, it shouldn't be used in production environment because it's really slow and inefficient in that case, and using proxy_pass wouldn't be a great idea if you are planning to release it.
With proxy_pass, you leave the 127.0.0.1:8080 server online, and then in nginx (on the same server), set up like that:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
The proxy_pass option redirects everything to the web.py server at 127.0.0.1:8080, the other ones - redirect the data about the connection (IP of the connected client and the host that was used for the connection on the nginx's side)
UWSGI
Using UWSGI, in short, is like that:
1) install uwsgi using your distro's package manager, or a pip, or using setup.py install.
2) in nginx, set up a server that will pass everything to the UWSGI server:
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9000;
}
}
3) Then, in your web.py application (let's suppose it's called yourappfile.py), instead of app.run(), use:
app = web.application(urls, globals())
application = app.wsgifunc()
You can still have app.run(), just make sure to put it inside the if __name__ == '__main__' block; and make sure the application = app.wsgifunc() is outside so UWSGI could see it.
Then start a UWSGI server:
uwsgi --http :9090 --wsgi-file yourappfile.py
Take a look at these manuals, it may help you:
UWSGI Quickstart
Web.py running on the nginx uwsgi
Deployment of Web.py Applications Using uWSGI and
Nginx
UWSGI Wiki - Examples
I created an endpoint on my flask which generates a spreadsheet from a database query (remote db) and then sends it as a download in the browser. Flask doesn't throw any errors. Uwsgi doesn't complain.
But when I check nginx's error.log I see a lot of
2014/12/10 05:06:24 [error] 14084#0: *239436 upstream prematurely
closed connection while reading response header from upstream, client:
34.34.34.34, server: me.com, request: "GET /download/export.csv HTTP/1.1", upstream: "uwsgi://0.0.0.0:5002", host: "me.com", referrer:
"https://me.com/download/export.csv"
I deploy the uwsgi like
uwsgi --socket 0.0.0.0:5002 --buffer-size=32768 --module server --callab app
my nginx config:
server {
listen 80;
merge_slashes off;
server_name me.com www.me.cpm;
location / { try_files $uri #app; }
location #app {
include uwsgi_params;
uwsgi_pass 0.0.0.0:5002;
uwsgi_buffer_size 32k;
uwsgi_buffers 8 32k;
uwsgi_busy_buffers_size 32k;
}
}
server {
listen 443;
merge_slashes off;
server_name me.com www.me.com;
location / { try_files $uri #app; }
location #app {
include uwsgi_params;
uwsgi_pass 0.0.0.0:5002;
uwsgi_buffer_size 32k;
uwsgi_buffers 8 32k;
uwsgi_busy_buffers_size 32k;
}
}
Is this an nginx or uwsgi issue, or both?
As mentioned by #mahdix, the error can be caused by Nginx sending a request with the uwsgi protocol while uwsgi is listening on that port for http packets.
When in the Nginx config you have something like:
upstream org_app {
server 10.0.9.79:9597;
}
location / {
include uwsgi_params;
uwsgi_pass org_app;
}
Nginx will use the uwsgi protocol. But if in uwsgi.ini you have something like (or its equivalent in the command line):
http-socket=:9597
uwsgi will speak http, and the error mentioned in the question appears. See native HTTP support.
A possible fix is to have instead:
socket=:9597
In which case Nginx and uwsgi will communicate with each other using the uwsgi protocol over a TCP connection.
Side note: if Nginx and uwsgi are in the same node, a Unix socket will be faster than TCP. See using Unix sockets instead of ports.
Change nginx.conf to include
sendfile on;
client_max_body_size 20M;
keepalive_timeout 0;
See self answer uwsgi upstart on amazon linux for full example
In my case, problem was nginx was sending a request with uwsgi protocol while uwsgi was listening on that port for http packets. So either I had to change the way nginx connects to uwsgi or change the uwsgi to listen using uwsgi protocol.
I had the same sporadic errors in Elastic Beanstalk single-container Docker WSGI app deployment. On EC2 instance of the environment upstream configuration looks like:
upstream docker {
server 172.17.0.3:8080;
keepalive 256;
}
With this default upstream simple load test like:
siege -b -c 16 -t 60S -T 'application/json' 'http://host/foo POST {"foo": "bar"}'
...on the EC2 led to availability of ~70%. The rest were 502 errors caused by upstream prematurely closed connection while reading response header from upstream.
The solution was to either remove keepalive setting from the upstream configuration, or which is easier and more reasonable, is to enable HTTP keep-alive at uWSGI's side as well, with --http-keepalive (available since 1.9).
Replace uwsgi_pass 0.0.0.0:5002; with uwsgi_pass 127.0.0.1:5002; or better use unix sockets.
It seems many causes can stand behind this error message. I know you are using uwsgi_pass, but for those having the problem on long requests when using proxy_pass, setting http-timeout on uWSGI may help (it is not harakiri setting).
There are many potential causes and solutions for this problem. In my case, the back-end code was taking too long to run. Modifying these variables fixed it for me.
Nginx:
proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout, fastcgi_send_timeout, fastcgi_read_timeout, keepalive_timeout, uwsgi_read_timeout, uwsgi_send_timeout, uwsgi_socket_keepalive.
uWSGI: limit-post.
I fixed this issue by passing socket-timeout = 65 (uwsgi.ini file) or --socket-timeout=65 (uwsgi command line) option in uwsgi. We have to check with different value depends on the web traffic. This value socket-timeout = 65 in uwsgi.ini file worked in my case.
I fixed this by reverting to pip3 install uwsgi.
I was trying out the setup with Ubuntu and Amazon Linux side by side. I initially used a virtual environment and did pip3 install uwsgi both systems work fine. Later, I did continue the setup with virtual env turned off. On Ubuntu I install using pip3 install uwsgi and on Amazon Linux yum install uwsgi -y. That was the source of the problem for me.
Ubuntu works fine, but not the Amazon Linux
The fix,
yum remove uwsgi and pip3 install uwsgi restart and it works fine.
This issue can also be caused by a mismatch between timeout values.
I had this issue when nginx had a keepalive_timeout of 75s, while the upstream server's value was a few seconds.
This caused the upstream server to close the connection when its timeout was reached, and nginx logged Connection reset by peer errors.
When having such abrupt "connection closed" errors, please check the upstream timeout values are higher than nginx' values (see Raphael's answer for a good list to check)