Getting a Flask website up and running in Ubuntu
This is a guide to get a Flask website up and running on Ubuntu 12.04 LTS using nginx and uWSGI. There are many routes to take when it comes to Python on the web; this just is my personal favorite. Some people enjoy configuring servers, while others view it as a chore. Regardless, this guide should get you up, running, and ready to make something awesome in no time!
Installation
nginx
To install nginx you first need to add the repository. Add the following to /etc/apt/sources.list.d/nginx-lucid.list
:
1
2
deb http://nginx.org/packages/ubuntu/ lucid nginx
deb-src http://nginx.org/packages/ubuntu/ lucid nginx
You will also want to add the gpg key to the apt
keyring:
1
2
3
wget http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
rm nginx_signing.key
Finally, to install nginx, run:
1
2
apt-get update
apt-get install nginx
uWSGI
You can use pip to install the latest version of uWSGI by doing the following:
1
2
sudo apt-get install python-dev build-essential python-pip
sudo pip install uwsgi
To configure uWSGI to run as a daemon, you first want to create a separate uwsgi
user:
1
sudo useradd -c 'uwsgi user,,,' -g nginx -d /nonexistent -s /bin/false uwsgi
You then want to create an upstart configuration file, to run uWSGI in the background. Add the following to /etc/init/uwsgi.conf
:
1
2
3
4
5
6
7
description "uWSGI"
start on runlevel [2345]
stop on runlevel [06]
respawn
exec uwsgi --master --processes 4 --die-on-term --uid uwsgi --gid nginx --socket /tmp/uwsgi.sock --chmod-socket 660 --no-site --vhost --logto /var/log/uwsgi.log
To set up logging, you can add a logrotate configuration file at /etc/logrotate.d/uwsgi
:
1
2
3
4
5
6
7
8
9
10
/var/log/uwsgi.log {
rotate 10
daily
compress
missingok
create 640 uwsgi adm
postrotate
initctl restart uwsgi >/dev/null 2>&1
endscript
}
and to prime the log file, you can run:
1
2
sudo touch /var/log/uwsgi.log
sudo logrotate -f /etc/logrotate.d/uwsgi
It is okay if there is an error with the postrotate script. uWSGI cannot be restarted because it is not currently running.
virtualenv
Using virtualenv is a good idea because it compartmentalizes the environment of your application. To install virtualenv, you can use pip:
1
sudo pip install virtualenv
Configuration
Flask
Now to set up the website! In this case, the website is going to be called ‘helloworld’ and it is going to be set up in /srv/www/helloworld
. Feel free to change it, just adjust these instructions accordingly.
The first step is to create the directory:
1
sudo mkdir -p /srv/www/helloworld
and a subdirectory for static files, to be hosted by nginx:
1
2
cd /srv/www/helloworld
mkdir static
The next step is to create a virtual environment for the application to run in:
1
virtualenv ./env
and to install Flask in that environment:
1
2
3
source env/bin/activate
pip install Flask
deactivate
Now that that is done, let’s create a sample ‘Hello World’ application, in application.py
:
1
2
3
4
5
6
7
8
9
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
The permissions of the directory now have to be configured. uWSGI needs read permission to read the contents of the scripts, and write permission to save compiled python files:
1
2
3
sudo usermod -a -G nginx $USER
sudo chown -R $USER:nginx /srv/www/helloworld
sudo chmod -R g+w /srv/www/helloworld
Nginx
The final step is to configure nginx. First, remove the default configuration file:
1
sudo rm /etc/nginx/conf.d/default.conf
Now, add the helloworld configuration file at /etc/nginx/conf.d/helloworld.conf
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 80;
server_name localhost;
location /static {
alias /srv/www/helloworld/static;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
uwsgi_param UWSGI_PYHOME /srv/www/helloworld/env;
uwsgi_param UWSGI_CHDIR /srv/www/helloworld;
uwsgi_param UWSGI_MODULE application;
uwsgi_param UWSGI_CALLABLE app;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Running it
Now that you have successfully configured your website, you can run it using:
1
2
sudo service uwsgi restart
sudo service nginx restart
Extensions
Flask
Flask is fantastic because it is very extensible. Check out the documentation to get started.
More Websites!
It is really easy to add more websites to this configuration. Simply create a new application directory, set it up, and create a second nginx configuration. uWSGI is configured to be in virtualhost mode, so it can handle multiple websites at once.
Portability
You can also use uWSGI as an http server, for testing purposes. If you have a copy of your website checked out in the current directory, you can run
1
uwsgi --http 127.0.0.1:9090 --pyhome ./env --module application --callable app
and uWSGI will create a HTTP server hosting your application on port 9090. This is incredibly useful for development.
Discuss on Hacker News here.