Quickstart
This is a series of deployment tutorial with various combos.
WARNING the following tutorials are based on the official releases, if you are using a debian-based package (that is fully modular) you will need to load the http and python plugins adding --plugins http,python to your command line.
uWSGI-http+WSGI app
A simple WSGI app, just for starting
(we will put it under /var/www/hello.py)
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return "Hello World"
Install uWSGI
pip install uwsgi
Run on http port 9090
uwsgi --http :9090 --wsgi-file /var/www/hello.py
go to localhost:9090 with your webbrowser
uWSGI-http+Django
Install uWSGI (if it is not already installed)
pip install uwsgi
Configure for django on HTTP port 8000 using a ini config file (call it django.ini if you like)
The app project is in /var/www/myapp
For a Django version >= 1.4 use that file (replace myapp with your project name):
[uwsgi] # set the http port http = :8000 # change to django project directory chdir = /var/www/myapp # load django module = myapp.wsgi
for previous Django versions you need a couple more options:
[uwsgi] # set the http port http = :8000 # change to django project directory chdir = /var/www/myapp # add /var/www to the pythonpath, in this way we can use the project.app format pythonpath = /var/www # set the project settings name env = DJANGO_SETTINGS_MODULE=myapp.settings # load django module = django.core.handlers.wsgi:WSGIHandler()
and finally run it
uwsgi --ini django.ini
You can reach your app on port 8000 with your browser
Nginx+uWSGI+flask
When you want to put uWSGI behind a full webserver (read: proxied configuration), the best solution is using the uwsgi protocol instead of the http one. You will remove the impact of the (relatively-slow) http parsing, and you will get a set of features derivated by the use of a specialized protocol.
nginx supports the uwsgi protocol out-of-the-box starting from version 0.8.40 (if you have an older version please read RunOnNginx).
The objective is passing requests from nginx to uWSGI port :3031
We need to define a location stanza in nginx config
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
(do not forget to include the uwsgi_params file !!!)
after reloading nginx conf, it will start forwarding requests to uWSGI listening on address 127.0.0.1:3031
Now we will start the Flask app (it is under /var/www/apps/flaskapp.py) with 2 workers and on socket 127.0.0.1:3031.
Workers are used to increase the concurrency of your app. Spawning 2 workers, will mean generating 2 processes ready to serve requests.
uwsgi --socket 127.0.0.1:3031 --file /var/www/apps/flaskapp.py --callable app --processes 2
(--file is a shortcut for --wsgi-file)
The --callable option will instruct uwsgi to use the 'app' callable defined in your flask app (if you have set another name for your app simply pass it in the --callable option)
If you put your app under the pythonpath (for example in /usr/lib/python2.6/site-packages) you can load it simply with
uwsgi --socket 127.0.0.1:3031 --module flaskapp:app --processes 2
or you can set /var/www/apps directly as your pythonpath
uwsgi --socket 127.0.0.1:3031 --pythonpath /var/www/apps --module flaskapp:app --processes 2
Apache2+uWSGI+multiple flask apps
You can host multiple apps in the same uWSGI instance/process. We will try to load 2 flask apps under different "mountpoints", /foo and /bar
We have 2 files app1.py and app2.py under dir /var/apps
app1.py:
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return "<span style='color:red'>I am app 1</span>"
app2.py
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return "<span style='color:green'>I am app 2</span>"
Now run uWSGI on tcp port 3031 on address 127.0.0.1 with 8 processes and a master
uwsgi --socket :3031 --pythonpath /var/apps --mount /foo=app1:app --mount /bar=app2:app --master --processes 8
or use the file-based form (does not require setting the pythonpath)
uwsgi --socket :3031 --callable app --mount /foo=/var/apps/app1.py --mount /bar=/var/apps/app2.py --master --processes 8
(the --callable option will instruct uWSGI to search for 'app' function instead of 'application')
Now the apache part.
First of all you need to install and enable the mod_uwsgi module.
If you are installing uWSGI from sources move to the apache2 directory and run
sudo apxs -i -a -c mod_uwsgi.c
this will compile mod_uwsgi and will enable it in your main configuration.
Now go to your virtualhost section (or put it in the main config if you are not using virtualhosting) and add
<Location /foo> SetHandler uwsgi-handler uWSGISocket 127.0.0.1:3031 </Location> <Location /bar> SetHandler uwsgi-handler uWSGISocket 127.0.0.1:3031 </Location>
Now reload your apache and check if all is working.
Remember: the first mounted app will be the default app, so, if you request /pippo from your browser you will see app1. You can disable this behaviour adding --no-default-app
You can delegate the management of the mountpoints to uWSGI itself. Modify the apache config to have only one main location
<Location /> SetHandler uwsgi-handler uWSGISocket 127.0.0.1:3031 </Location>
then add --manage-script-name to your uWSGI command line
Note: each one of your flask app will run under a different python interpreter (it is a python feature), so you can mess around with pythonpaths and modules without problems.
