Запускаем Python-приложения (Django, Flask, etc) через nginx и uwsgi на Ubuntu 12.04

Для примера возьмем Flask. На Django все делается аналогично, но как минимум нужно создать проект, настроить его, а это лишние файлы и телодвижения. А пример на Flask требует только одного файла.

Nginx и uWSGI — это веб сервера. Nginx нам нужен для отдачи статики и проксирования запросов к uWSGI. А uWSGI делает запросы питоновскому приложению и получает от него ответы. Взаимодействие между питоном и веб-сервером происходит по протоколу WSGI.

Наш проект будет располагаться в директории
/home/ilya/webapps/example.com/example/

Там будет лишь один файл (имя может быть любым) —
wsgi.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

Создаем в проекте виртуальное окружение и устанавливаем туда Flask.

$ cd /home/ilya/webapps/example.com/example/
$ virtualenv python
$ . python/bin/activate
$ pip install flask

Устанавливем необходимые пакеты:

sudo apt-get install nginx uwsgi uwsgi-plugin-python

Создаем конфиг для nginx:
/etc/nginx/sites-available/example.conf

server {
    listen 80;
    server_name example.com;
    
    location / {
        uwsgi_pass      unix:/var/run/example.sock;
        include         uwsgi_params;
    }

    location /static/ {
        alias /home/ilya/webapps/example.com/www/static/;
    }
}

Делаем симлинк в папку sites-enabled

sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/example.conf

Создаем конфиг для uwsgi в формате ini (также он понимает форматы xml, json и yaml).
/etc/uwsgi/apps-available/example.ini

[uwsgi]
plugins=python27
vhost=true
socket=/var/run/example.sock
virtualenv=/home/ilya/webapps/example.com/example/python/
module=wsgi
callable=app
pythonpath=/home/ilya/webapps/example.com/example
chdir=/home/ilya/webapps/example.com/example

где
module — имя нашего модуля wsgi.py
callable — это имя объекта в питоновском файле, в случае с джангой он называется «application».

Делаем симлинк в папку apps-enabled:

sudo ln -s /etc/uwsgi/apps-available/example.ini /etc/uwsgi/apps-enabled/example.ini

Перезапускаем оба сервера:

sudo service nginx reload
sudo service uwsgi reload

Проверяем доступность сайта. (Домен должен быть прописан в DNS или /etc/hosts.)

curl example.com

Замечания по отладке

У нас получается очень много настроек и все они связаны друг с другом. Например если nginx выдает ошибку то не понятно где ошибка, толи в настройках nginx, толи в настроках uwsgi толи в настройках питон приложения. Поэтому, если что-то не работает:
1) смотри логи серверов
2) смотри создался ли файловый сокет, указанный в настрйках
3) питоновский код можно запустить отдельно и проверить curl’ом

Ссылки по теме:
uWSGI Quickstart
uWSGI Docs
Nginx Documentation
WSGI
PEP 3333 — Python Web Server Gateway Interface