NGINX + UWSGI + Ubuntu 16

(Last Updated On: )

If you use Python as part of your stack in developing a web architecture you most likely will also be utilizing NGINX with UWSGI together. In the following article I will give step by step instructions on how to set this up assuming you are using sockets as part of your installation.

What is UWSGI?: A full stack for building application servers for python and various other languages.

What is NGINX?: Is simply a web server or proxy server for various protocols but can also do load balancing, etc.

NGINX Installation:

  1. sudo apt-get install nginx
  2.  
  3. #The next command checks that nginx is running
  4. ps -auxw | grep nginx
  5.  
  6. #Stop the service
  7. sudo service nginx stop
  8. #Start the service
  9. sudo service nginx start
  10. #Restart the service
  11. sudo service nginx restart
  12. #nginx status
  13. sudo service nginx status

Once it is installed you will have two folders. One called “sites-enabled” and one called “sites-available” located under /etc/nginx/ folder. The “sites-enabled” folder usually holds a symbolic link to the actual file sometimes in “sites-available” folder. But really can be hosted anywhere on the machine.

If you want to remove the default site link you can

  1. sudo rm /etc/nginx/sites-enabled/default

Create our symbolic link in sites-enabled if we already have a nginx.conf file ready.

  1. cd /etc/nginx/sites-enabled/
  2.  
  3. sudo ln -s ~/path/to/nginx/conf/nginx.conf nginx.conf

It’s important to note that you may run into permissions errors depending on where you are running your nginx.conf from. So you may need to grant permissions to your users home folder.

  1. sudo chmod 755 /home/user_your_run_your_app_from/

UWSGI Installation:

  1. sudo apt-get install uwsgi
  2.  
  3. #Stop uwsgi
  4. sudo service uwsgi stop
  5. #Start uwsgi
  6. sudo service uwsgi start
  7. #Restart uwsgi
  8. sudo service uwsgi restart
  9. #uwsgi status
  10. sudo service uwsgi status

It you want to log to a custom folder your uwsgi.ini file will need “logto” folder specified and the correct permissions set.

  1. cd /var/log/
  2. sudo touch /var/log/mylogfile
  3. sudo chmod 666 /var/log/mylogfile

You uwsgi.ini will also have a pid file “pidfile” which we will need to create.

  1. cd /tmp/
  2. touch mypid.pid
  3.  
  4. #Ownership
  5. sudo chown THEUSER:www-data mypid.pid
  6.  
  7. #Ensure permissions are set to -rw-r--r--

UWSGI INI Options:

You can add whatever options you prefer as part of your uwsgi.ini setup file. However the below are usually the ones you should use.

  1. [uwsgi]
  2. socket = :5006 #or whatever socket you want
  3. chmod-socket = 777
  4. pidfile=/tmp/mypid.pid
  5. master = True
  6. chdir = /home/user_your_run_your_app_from/
  7.  
  8. #NOTE that you may or may not need this depending on how you setup your server.
  9. plugin = python3
  10. wsgi_file = my_python_class.py #File that runs your application
  11. module = whatever
  12. callable = app #Set default WSGI callable name.
  13. logto = /var/log/mylogfile

These are not all the options you can pick. You can also set “stats”, “buffer-size”, “processes”, “threads”, “env”, etc. Just review the docs and pick what is right for you.

The option “env” you can add many times and for each time you use it you can set environment variable for use with your application.

NOTE: If you are running flask and use send_file and run as Python3.5 you may get the error “SystemError: <built-in function uwsgi_sendfile> returned a result with an error set”. If you do then you must add the following to your uwsgi.ini file “wsgi-disable-file-wrapper = true”.

NGINX Conf Example:

  1. upstream flask {
  2. server 0.0.0.0:5006;
  3. }
  4. server {
  5. client_max_body_size 1G;
  6. listen 0.0.0.0:8081;
  7. server_name localhost;
  8. access_log /var/log/nginx/access_log combined;
  9. location / {
  10. include uwsgi_params;
  11. uwsgi_pass flask;
  12. }
  13. location /static/ {
  14. alias /path/to/my/app/static/;
  15. }
  16. }
  17. fastcgi_intercept_errors on;

UWSGI Service:

Sometimes we want to run our app as a service if you do then below are the steps for that.

  1. sudo nano /etc/systemd/system/myawesomeservice.service
  2.  
  3. #Enter the contents below
  4.  
  5. [Unit]
  6. Description=uWSGI instance to serve My Service
  7. After=network.target
  8. [Service]
  9. User=user_to_run_as
  10. Group=www-data
  11. WorkingDirectory=/path/to/my/app/
  12. ExecStart=/usr/bin/env bash -c 'uwsgi --ini /path/to/my/app/uwsgi.ini --uid user_to_run_as --gid www-data'
  13. Restart=always
  14. RestartSec=3
  15. [Install]
  16. WantedBy=multi-user.target

Next you need to ensure the user has access to your folder with correct ownerships.

  1. chown -R user_to_run_as:www-data /path/to/my/app/*

Next enable the service and start the service.

  1. sudo systemctl enable myawesomeservice
  2. sudo systemctl daemon-reload
  3. sudo systemctl start myawesomeservice
  4. sudo service myawesomeservice status