Let’s get straight to the point. I have a Flask app that I want to run on Ubuntu. I shall use uwsgi and nginx. Upstart will be used to monitor the process and restart it if it’s killed or dies an untimely death.
Running the uWSGI app with nginx
It’s very easy to run Flask apps with uwsgi, just cd into the directory where your main app file exists and pass the uwsgi module name. If your main app file is called “main.py” and if your Flask app instance is called “app” inside main.py, then your uWSGI module name would be “main:app” from the directory where main.py resides.
1 2 |
cd /home/dev/awesome-flask-app uwsgi --socket 127.0.0.1:8080 -w main:app |
Now, we need to configure nginx:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
upstream flaskapp { server 127.0.0.1:8080; } server { listen 80; location / { include uwsgi_params; uwsgi_pass flaskapp; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } } |
Here, we first need to define an upstream. We define the “flaskapp” upstream for our app. Then inside the location block, we use it as the source of our uwsgi_pass directive. It would tell nginx to connect to the uwsgi server we defined and serve as a bridge between the internet and the flask uwsgi app.
Upstarting the uWSGI process
Now, what happens if our uWSGI process dies? nginx would no longer be able to connect to the app and throw a “bad gateway” error. So we need to make sure that if the process dies from an error or somehow gets killed, it is restarted automatically. There are a few tools which can do this. Supervisord is the most popular one, Circus is also very nice. However, I like to use Upstart for cases like this. Upstart comes with Ubuntu and used by the OS for many of it’s own services. It’s easy to use, already available, reliable and most importantly – it allows me to create a service too!
To create our upstart config, we cd into “/etc/init” and create a new file named “flaskapp.conf”. Then we put the following contents in there:
1 2 3 4 5 6 7 8 9 |
start on runlevel [2345] stop on runlevel [016] respawn script cd /home/dev/awesome-flask-app exec uwsgi --socket 127.0.0.1:8080 -w main:app end script |
Here, we’re telling Upstart to launch our app on startup and respawn whenever the process dies. We put our commands in a script block. We have defined our service, now time to fire it up. If you have any uwsgi process run with the same config, first kill them. Then run this command to start the service:
1 |
sudo service flaskapp start |
Right, you can use the usual “start|stop|restart|status” service commands with it. The service name is derived from the file name we used in “/etc/init”. The log of the process would be found in “/var/log/upstart/flaskapp.log”.
From Upstart to Systemd
Ubuntu is moving away from Upstart to systemd. Most of my apps use Ubuntu 14.04 LTS so I can still use Upstart fine. However, if your version of Ubuntu doesn’t ship Upstart, you can use systemd for similar tasks. Here’s the link: systemd for upstart users