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:
sudo apt-get install nginx #The next command checks that nginx is running ps -auxw | grep nginx #Stop the service sudo service nginx stop #Start the service sudo service nginx start #Restart the service sudo service nginx restart #nginx status 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
sudo rm /etc/nginx/sites-enabled/default
Create our symbolic link in sites-enabled if we already have a nginx.conf file ready.
cd /etc/nginx/sites-enabled/ 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.
sudo chmod 755 /home/user_your_run_your_app_from/
UWSGI Installation:
sudo apt-get install uwsgi #Stop uwsgi sudo service uwsgi stop #Start uwsgi sudo service uwsgi start #Restart uwsgi sudo service uwsgi restart #uwsgi status 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.
cd /var/log/ sudo touch /var/log/mylogfile sudo chmod 666 /var/log/mylogfile
You uwsgi.ini will also have a pid file “pidfile” which we will need to create.
cd /tmp/ touch mypid.pid #Ownership sudo chown THEUSER:www-data mypid.pid #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.
[uwsgi] socket = :5006 #or whatever socket you want chmod-socket = 777 pidfile=/tmp/mypid.pid master = True chdir = /home/user_your_run_your_app_from/ #NOTE that you may or may not need this depending on how you setup your server. plugin = python3 wsgi_file = my_python_class.py #File that runs your application module = whatever callable = app #Set default WSGI callable name. 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:
upstream flask { server 0.0.0.0:5006; } server { client_max_body_size 1G; listen 0.0.0.0:8081; server_name localhost; access_log /var/log/nginx/access_log combined; location / { include uwsgi_params; uwsgi_pass flask; } location /static/ { alias /path/to/my/app/static/; } } 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.
sudo nano /etc/systemd/system/myawesomeservice.service #Enter the contents below [Unit] Description=uWSGI instance to serve My Service After=network.target [Service] User=user_to_run_as Group=www-data WorkingDirectory=/path/to/my/app/ ExecStart=/usr/bin/env bash -c 'uwsgi --ini /path/to/my/app/uwsgi.ini --uid user_to_run_as --gid www-data' Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
Next you need to ensure the user has access to your folder with correct ownerships.
chown -R user_to_run_as:www-data /path/to/my/app/*
Next enable the service and start the service.
sudo systemctl enable myawesomeservice sudo systemctl daemon-reload sudo systemctl start myawesomeservice sudo service myawesomeservice status