This is a porting of set up sourced from DigitalOcean's tutorial of How To Serve Flask Applications with uWSGI and Nginx on Ubuntu 14.04
and some useful git resources for nginx servers.
Flask Application
This tutorial assume you use Ubuntu.
var/www/
folder.mkdir myexample
cd myexample
optional You may want to set up virtual environment for deploying web applications on production server.
sudo pip install virtualenv
to install virtual environment.
virtualenv myexample
to set up virtual environment for your app.
source myprojectenv/bin/activate
to activate your environment. Here you will install all python packages.
end optional but recommended
Set up flask and gateway uWSGI
Install flask and uSWGI gateway:
pip install uwsgi flask
Example of flask app in myexample.py:
from flask import Flask
application = Flask(__name__)
@application.route("/")
def hello():
return "<h1>Hello World</h1>"
if __name__ == "__main__":
application.run(host='0.0.0.0')
Create file to communicate between your web app and the web server: gateway interface [https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface]
nano wsgi.py
then import your webapp module and make it run from the gateway entry point.
from myexample import application
if __name__ == "__main__":
application.run()
To test uWSGI:
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi
To configure uWSGI:
Create a configuration file .ini
nano myexample.ini
Basic configuration for gateway uWSGI
# include header for using uwsgi
[uwsgi]
# point it to your python module wsgi.py
module = wsgi
# tell uWSGI to start a master node to serve requests
master = true
# spawn number of processes handling requests
processes = 5
# use a Unix socket to communicate with Nginx. Nginx will pass connections to uWSGI through a socket, instead of using ports. This is preferable because Nginx and uWSGI stays on the same machine.
socket = myexample.sock
# ensure file permission on socket to be readable and writable
chmod-socket = 660
# clean the socket when processes stop
vacuum = true
# use die-on-term to communicate with Ubuntu versions using Upstart initialisations: see:
# http://uwsgi-docs.readthedocs.io/en/latest/Upstart.html?highlight=die%20on%20term
die-on-term = true
optional if you are using virtual env You can deactivate
your virtual environment.
Nginx configuration We are gonna use nginx as:
Locate your sites-available
directory and create a configuration file for your application:
sudo nano /etc/nginx/sites-available/myexample
Add following block, in comments what it does:
server {
# setting up default server listening to port 80
listen 8000 default_server;
server_name myexample.com; #you can also use your IP
# specify charset encoding, optional
charset utf-8;
# specify root of your folder directory
root /var/www/myexample;
# specify locations for your web apps.
# here using /api endpoint as example
location /api {
# include parameters of wsgi.py and pass them to socket
include uwsgi_params;
uwsgi_pass unix:/var/www/myexample/myexample.sock;
}
}
# Here you will specify caching zones that will be used by your virtual server
# Cache will be stored in /tmp/nginx folder
# ensure nginx have permissions to write and read there!
# See also:
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
# set up the virtual host!
server {
listen 80 default_server;
# Now www.example.com will listen to port 80 and pass request to http://example.com
server_name www.example.com;
# Why not caching responses
location /api {
# set up headers for caching
add_header X-Proxy-Cache $upstream_cache_status;
# use zone specified above
proxy_cache my_zone;
proxy_cache_use_stale updating;
proxy_cache_lock on;
# cache all responses ?
# proxy_cache_valid 30d;
# better cache only 200 responses :)
proxy_cache_valid 200 30d;
# ignore headers to make cache expire
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
# pass requests to default server on port 8000
proxy_pass http://example.com:8000/api;
}
}
Finally, link the file to sites-enabled
directory.
For an explanation of available and enabled sites, see answer:
[http://serverfault.com/a/527644]
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
You are done now with nginx. However, you may want to check out this very precious boiler template: [https://github.com/h5bp/server-configs-nginx]
Very useful for fine tuning.
Now test Nginx:
sudo nginx -t
Launch Nginx:
sudo service nginx restart
Automate Ubuntu to start uWSGI The last thing is to make Ubuntu start the wsgi gateway communicating with your application, otherwise you should do it manually.
sudo nano /etc/init/myexample.conf
Add following block, comments in line to explain what it does
# description for the purpose of this script
description "uWSGI server instance configured to serve myproject"
# Tell to start on system runtime 2, 3, 4, 5. Stop at any other level (0,1,6).
# Linux run levels: [http://www.debianadmin.com/debian-and-ubuntu-linux-run-levels.html]
start on runlevel [2345]
stop on runlevel [!2345]
# Set up permissions! "User" will be the username of your user account on ubuntu.
setuid user
# Allow www-data group to read and write from the socket file.
# www-data is normally the group Nginx and your web applications belong to.
# you may have all web application projects under /var/www/ that belongs to www-data group
setgid www-data
# tell Ubunutu which environment to use.
# This is the path of your virtual environment: python will be in this path if you installed virtualenv. Otherwise, use path of your python installation
env PATH=/var/www/myexample/myexample/bin
# then tell to Ubuntu to change and locate your web application directory
chdir /var/www/myexample
# finally execute initialisation script, that load your web app myexample.py
exec uwsgi --ini myexample.ini
Now you can activate your script: sudo start myexample