While Python projects deployed using Nginx and uWSGI can have an overwhelming number configuration options available, deploying basic apps with them can actually be pretty painless. Here's one simple option for setting up your LEMP stack on Ubuntu and deploying a Flask application.
If you're just interested in following the Redmine tutorial it is not necessary to install uWSGI.
Before installing any new software, make sure your system is up to date. If installing MariaDB, you'll first need to add the right repository for your release. The below example adds a repository for MariaDB 5.5 on Ubuntu 12.04.
sudo apt-get install python-software-properties
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu precise main'
Regardless of whether or not you're installing MariaDB, update your package lists and upgrade any necessary packages.
sudo apt-get update
sudo apt-get -y upgrade
Install pip and some dependent packages.
sudo apt-get -y install build-essential debconf-utils python-dev libpcre3-dev libssl-dev python-pip
If the appropriate repository was added, begin MariaDB installation. During this installation you'll be asked to set a password for the MariaDB root user.
apt-get -y install mariadb-server
Once the installation finishes, run a script and follow the prompts to secure it.
mysql_secure_installation
The Nginx package installed by the Ubuntu repository will likely be much older than the current release. This should work just fine for your app, but you'll miss out any new features and fixes.
sudo apt-get -y install nginx
If you want the newest version of Nginx, you can add the repository for the latest stable release.
sudo add-apt-repository ppa:nginx/stable
sudo apt-get update
sudo apt-get -y install nginx
Visit your server's hostname or IP address in your browser. If the installation was successful you'll see a placeholder site that can be disabled by removing its link in sites-enabled.
sudo rm /etc/nginx/sites-enabled/default
Create a new site configuration for you application. Here we're using a Unix socket instead of TCP.
sudo nano /etc/nginx/sites-available/flaskapp
server {
listen 80;
server_name $hostname;
location /static {
alias /srv/www/flaskapp/app/static;
}
location / { try_files $uri @flaskapp; }
location @flaskapp {
include uwsgi_params;
uwsgi_pass unix:/tmp/flaskapp.sock;
}
}
Create directories for your site and link the site's configuration to sites-enabled so Nginx will use it.
sudo mkdir -p /srv/www/flaskapp/app/static
sudo mkdir -p /srv/www/flaskapp/app/templates
sudo ln -s /etc/nginx/sites-available/flaskapp /etc/nginx/sites-enabled/flaskapp
Optional if you're just following the Redmine installation tutorial.
Install uWSGI with pip and create directories for configuration files and logs.
pip install uwsgi
mkdir /etc/uwsgi
mkdir /var/log/uwsgi
Emperor mode is great for handling apps because it will spawn, stop, and reload processes as necessary. In this deployment the Emperor is started via Upstart with very basic parameters to allow for more flexibility when configuring applications.
sudo nano /etc/init/uwsgi-emperor.conf
description "uWSGI Emperor"
start on runlevel [2345]
stop on runlevel [06]
exec uwsgi --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uwsgi.log
Create a uWSGI configuration file for your application.
sudo nano /etc/uwsgi/flaskapp.ini
[uwsgi]
chdir = /srv/www/flaskapp
logto = /var/log/uwsgi/flaskapp.log
virtualenv = /srv/www/flaskapp/venv
socket = /tmp/flaskapp.sock
uid = www-data
gid = www-data
master = true
wsgi-file = wsgi.py
callable = app
vacuum = true`</pre>
Create a simple application file to test the configuration.
sudo nano /srv/www/flaskapp/wsgi.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "It works!"
Install Flask within a virtualenv.
sudo pip install virtualenv
cd /srv/www/flaskapp
virtualenv venv
source venv/bin/activate
pip install flask
Change the permissions so www-data can access application files.
sudo chgrp -R www-data /srv/www/*
sudo chmod -R g+rw /srv/www/*
sudo sh -c 'find /srv/www/* -type d -print0 | sudo xargs -0 chmod g+s'
Start uWSGI and restart Nginx.
start uwsgi-emperor
service nginx restart
Visit your server's hostname or IP in your browser once again. You should see, "It works!"