Skip to content

Instantly share code, notes, and snippets.

@b0bu
Created August 31, 2016 14:08
Show Gist options
  • Save b0bu/a6aec14166d62b4f8f013415a2c1f757 to your computer and use it in GitHub Desktop.
Save b0bu/a6aec14166d62b4f8f013415a2c1f757 to your computer and use it in GitHub Desktop.
Running uwsgi/wsgi with nginx for dummies
Running wsgi with nginx for dummies
This was written while trying to get ceph-dash monitoring flask api to work with nginx, I'm sure some of the concepts here could be applied to
just about any app you're trying to serve through nginx.
So ever wanted to know how to fix all the problems?
FIX FOR 500 RESPONSE CODE
Nginx is NOT starting any wsgi processes for you, I had to start this server manually. In order to get this to work from uwsgi the full path MUST be given to .wsgi file.
All files owned by nginx in /etc/nginx/sites-enabled
WORKING
uwsgi server doing the http business
uwsgi --socket 0.0.0.0:5000 --protocol=http --wsgi-file /etc/nginx/sites-enabled/ceph-dash/contrib/wsgi/cephdash.wsgi
WORKING
uwsgi --ini uwsgi.ini
[uwsgi]
chdir = /etc/nginx/sites-enabled/ceph-dash
wsgi-file = /etc/nginx/sites-enabled/ceph-dash/contrib/wsgi/cephdash.wsgi
enable-threads = true
master = true
processes = 4
http-socket = 0.0.0.0:5000 # uwsgi server doing the http business
vacuum = true
uid = nginx
gid = nginx
daemonize = /tmp/ceph-dash.log
FIX FOR BAD GATEWAY 502 Bad Gateway (nginx can't find uwsgi server)
start the uwsgi server and make sure the next fix 503 is in place
FIX FOR BAD GATEWAY 503 (uwsgi server reachable but not able to process request)
The point of wsgi protocol (natively supported by nginx) is that it can proxy_pass requests off to the uwsgi server, ** in a wsgi binary format ** the http is handled by the listening nginx port 5000.
WORKING
uwsgi --ini uwsgi.ini
[uwsgi]
chdir = /etc/nginx/sites-enabled/ceph-dash
wsgi-file = /etc/nginx/sites-enabled/ceph-dash/contrib/wsgi/cephdash.wsgi
enable-threads = true
master = true
processes = 4
socket = :3000 # curl: (52) Empty reply from server, NOT handling http business
vacuum = true
uid = nginx
gid = nginx
daemonize = /tmp/ceph-dash.log
Now start nginx with this config
upstream uwsgi {
server 127.0.0.1:3000; # native wsgi protocol being passed here
}
server {
listen 5000; # handling all the http business
server_name what.ever.com
charset utf-8;
location / {
uwsgi_pass uwsgi;
include /etc/nginx/sites-enabled/ceph-dash/contrib/nginx/uwsgi_params;
}
}
The response for this is successful
curl -I localhost:5000
HTTP/1.1 200 OK
Server: nginx/1.6.3
Date: Wed, 31 Aug 2016 13:03:07 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 7794
Connection: keep-alive
FIX FOR USING .SOCK FILE
If uwsgi can't create the socket the server won't start. You can quickly find out if it started with pgrep uwsgi. If it returns nothing then it's not running you can also check manually if the socket created.
NOTES
uwsgi could not create a socket in /var/run because of the user I was starting it with
uwsgi could create a socket with socket = /tmp/ceph-dash.sock however programs starting a socket in /tmp can only be seen by the program that created it. So nginx can't connect to it.
I created a dir /var/run/uwsgi and chown'd it with the user I was running uwsgi with i.e. cephuser. Now uwsgi could create it but nginx still couldn't access it to pass to because it now does not have permission. To get around this I just set the chmod-socket permissions to 777 and restarted uwsgi, it worked.
It's not ideal and there's probably a better way to either host that server with the same user running wsgi or have a group with shared membership access.
WORKING
[uwsgi]
chdir = /etc/nginx/sites-enabled/ceph-dash
wsgi-file = /etc/nginx/sites-enabled/ceph-dash/contrib/wsgi/cephdash.wsgi
enable-threads = true
master = true
processes = 4
socket = /var/run/uwsgi/ceph-dash.socket
chmod-socket = 777
vacuum = true
uid = nginx
gid = nginx
#daemonize = /var/log/uwsgi/ceph-dash.log
daemonize = /tmp/ceph-dash.log
And comfirmation:
/var/run/uwsgi/
srw-rw-r--. 1 cephuser cephuser 0 Aug 31 14:11 ceph-dash.sock
Finally change the nginx upsteam block and restart nginx and voilà, pay dirt.
upstream uwsgi {
server unix:////var/run/uwsgi/ceph-dash.sock;
}
@gbdlin
Copy link

gbdlin commented Sep 1, 2016

Some advices for you:

  1. if you're running your nginx server from nginx user and nginx group, DON'T run your uWSGI server from it. It is an security hole... if there is a hole in your wsgi application, attacker will be able to access nginx directly and modify it's configs (for example to serve his own domains or something). Also if you're running more sites on that server, attacker will be able to access them as well and tamper their responses. To fix it, create separate user for your wsgi app, chown all app files by this user and chmod socket for 770. Also, make sure that wsgi app is running on group named after user and all application files are owned by that group. This will be needed in 3rd advice.
  2. chown /var/run/uwsgi by root and chmod it to 1777. That 1 at the beginning will prevent any user from tampering file created by other user. Same flag is used in /tmp/ directory... Don't worry, your nginx server will be able to access that socket after next advice.
  3. add nginx (or www-data, if your nginx server is running on that user) to group named after user that is owning your wsgi app. That way, nginx will have access to that application and it's socket file, but not other way around (app won't have access to nginx process and it's files).

Also, if there is anything on your system, that you don't want to be accessible by your wsgi application (for example other websites hosted on that server), make sure to store them on other user account and chmod them 750 or 640 if needed.

@b0bu
Copy link
Author

b0bu commented Sep 5, 2016

Thanks for your input. I will apply a few of these to production when it's implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment