Хостинг Python проекта — настройка uWSGI по шагам

Хостинг Python проекта — настройка uWSGI по шагам

Разберем по шагам процесс и детали настройки хостинга для Python проекта с использованием uWSGI на примере Django.

Кроме nginx и uWSGI на сервере вам понадобятся PIP и Virtualenv-wrapper, а также Python dev packages.

Я рекомендую VPS от DigitalOcean. Удобное управление, низкие цены — идеально для хостинга своего проекта. Плюс сервера в этом облаке в несколько раз быстрее чем в Amazon EC2 при равной цене или даже меньшей в DigitalOcean.

Регистрация по этой ссылке даст 10$ в кредит:

Этого достаточно для бесплатной работы сервера 2 месяца.

Принцип работы uWSGI

A web server faces the outside world. It can serve files (HTML, images, CSS, etc) directly from the file system. However, it can’t talk directly to Django applications; it needs something that will run the application, feed it requests from web clients (such as browsers) and return responses.

A Web Server Gateway Interface — WSGI — does this job. WSGI is a Python standard.

uWSGI is a WSGI implementation. In this tutorial we will set up uWSGI so that it creates a Unix socket, and serves responses to the web server via the WSGI protocol. At the end, our complete stack of components will look like this:

Подготовка к установке uWSGI

Установка pip, python-dev, virtualenvwrapper

Установка Python dev packages

Создание виртуального окружения

Make sure you are in a virtualenv for the software we need to install (we will describe how to install a system-wide uwsgi later):

Установка Django

Install Django into your virtualenv, create a new project, and cd into the project:

Про домен и порт

In this tutorial we will call your domain example.com. Substitute your own FQDN or IP address.

Throughout, we’ll using port 8000 for the web server to publish on, just like the Django runserver does by default. You can use whatever port you want of course, but I have chosen this one so it doesn’t conflict with anything a web server might be doing already.

Установка и начальная настройка uWSGI

Установка uWSGI в виртуальном окружении

Of course there are other ways to install uWSGI, but this one is as good as any. Remember that you will need to have Python development packages installed. In the case of Debian, or Debian-derived systems such as Ubuntu, what you need to have installed is pythonX.Y-dev, where X.Y is your version of Python.

Проверка работы

Create a file called test.py:

The options mean:

  • http :8000: use protocol http, port 8000
  • wsgi-file test.py: load the specified file, test.py

This should serve a ‘hello world’ message directly to the browser on port 8000. Visit:

to check. If so, it means the following stack of components works:

Проверка работы Django проекта

Now we want uWSGI to do the same thing, but to run a Django site instead of the test.py module.

If you haven’t already done so, make sure that your mysite project actually works:

And if it that works, run it using uWSGI:

  • module mysite.wsgi: load the specified wsgi module

Point your browser at the server; if the site appears, it means uWSGI is able serve your Django application from your virtualenv, and this stack operates correctly:

Now normally we won’t have the browser speaking directly to uWSGI. That’s a job for the webserver, which will act as a go-between.

Настройка nginx

Установка nginx

And now check that the nginx is serving by visiting it in a web browser on port 80 — you should get a message from nginx: “Welcome to nginx!”. That means these components of the full stack are working together:

If something else is already serving on port 80 and you want to use nginx there, you’ll have to reconfigure nginx to serve on a different port. For this tutorial though, we’re going to be using port 8000.

Настройка вашего сайта в nginx

Скачайте файл uwsgi_params с https://github.com/nginx/nginx/blob/master/conf/uwsgi_params, либо просто создайте его, поместив туда текст:

Copy it into your project directory. In a moment we will tell nginx to refer to it.

Now create a file called mysite_nginx.conf, and put this in it:

This conf file tells nginx to serve up media and static files from the filesystem, as well as handle requests that require Django’s intervention. For a large deployment it is considered good practice to let one server handle static/media files, and another handle Django applications, but for now, this will do just fine.

Symlink to this file from /etc/nginx/sites-enabled so nginx can see it:

Проверка работы nginx

To check that media files are being served correctly, add an image called media.png to the/path/to/your/project/project/media directory, then visithttp://example.com:8000/media/media.png — if this works, you’ll know at least that nginx is serving files correctly.

It is worth not just restarting nginx, but actually stopping and then starting it again, which will inform you if there is a problem, and where it is.

Тест nginx и uWSGI с test.py

Let’s get nginx to speak to the “hello world” test.py application.

This is nearly the same as before, except this time one of the options is different:

  • socket :8001: use protocol uwsgi, port 8001

nginx meanwhile has been configured to communicate with uWSGI on that port, and with the outside world on port 8000. Visit:

to check. And this is our stack:

Meanwhile, you can try to have a look at the uswgi output at http://example.com:8001 — but quite probably, it won’t work because your browser speaks http, not uWSGI, though you should see output from uWSGI in your terminal.

Использование Unix sockets вместо сетевого порта

So far we have used a TCP port socket, because it’s simpler, but in fact it’s better to use Unix sockets than ports — there’s less overhead.

Edit mysite_nginx.conf, changing it to match:

and restart nginx.

Runs uWSGI again:

This time the socket option tells uWSGI which file to use.

Если не заработало

Check your nginx error log(/var/log/nginx/error.log). If you see something like:

then probably you need to manage the permissions on the socket so that nginx is allowed to use it.

You may also have to add your user to nginx’s group (which is probably www-data), or vice-versa, so that nginx can read and write to your socket properly.

It’s worth keeping the output of the nginx log running in a terminal window so you can easily refer to it while troubleshooting.

Запуск приложения Django с uswgi и nginx

Let’s run our Django application:

Now uWSGI and nginx should be serving up not just a “Hello World” module, but your Django project.

Настройка uWSGI для запуска через .ini файл

We can put the same options that we used with uWSGI into a file, and then ask uWSGI to run with that file. It makes it easier to manage configurations.

Create a file called `mysite_uwsgi.ini`:

And run uswgi using this file:

Once again, test that the Django site works as expected.

Запуск uwsgi в режиме демона

Чтобы запустить uwsgi в режиме демона, создайте каталог /var/log/uwsgi и добавьте в файл конфигурации строку:

После этого uwsgi будет использовать указанный файл для вывода всех сообщений. Чтобы просмотреть вывод, запустите в консоли

Завершение настройки веб-сервера

Установка uWSGI в системе

So far, uWSGI is only installed in our virtualenv; we’ll need it installed system-wide for deployment purposes.

Deactivate your virtualenv:

and install uWSGI system-wide:

The uWSGI wiki describes several installation procedures. Before installing uWSGI system-wide, it’s worth considering which version to choose and the most apppropriate way of installing it.

Check again that you can still run uWSGI just like you did before:

Emperor mode

uWSGI can run in ‘emperor’ mode. In this mode it keeps an eye on a directory of uWSGI config files, and will spawn instances (‘vassals’) for each one it finds.

Whenever a config file is amended, the emperor will automatically restart the vassal.

You may need to run uWSGI with sudo:

The options mean:

  • emperor: where to look for vassals (config files)
  • uid: the user id of the process once it’s started
  • gid: the group id of the process once it’s started

Check the site; it should be running.

Автозапуск uWSGI при загрузке сервере

The last step is to make it all happen automatically at system startup time.

Edit /etc/rc.local and add:

before the line “exit 0”.

And that should be it!

Дальнейшая настройка веб-сервера

It is important to understand that this has been a tutorial, to get you started. You do need to read the nginx and uWSGI documentation, and study the options available before deployment in a production environment.

Both nginx and uWSGI benefit from friendly communities, who are able to offer invaluable advice about configuration and usage.


General configuration of nginx is not within the scope of this tutorial though you’ll probably want to it to listen on port 80, not 8000, for a production website.

You also ought to consider at having a separate server for non-Django serving, of static files for example.


uWSGI supports multiple ways to configure it. See uWSGI’s documentation and examples.

Some uWSGI options have been mentioned in this tutorial; others you ought to look at for a deployment in production include (listed here with example settings):

Running uWSGI via Upstart

Upstart is the init system of Ubuntu-like distributions.

It is based on declarative configuration files – not shell scripts of yore – that are put in the /etc/init directory.

A simple script (/etc/init/uwsgi.conf)

Using the Emperor

A better approach than init files for each app would be to only start an Emperor via Upstart and let it deal with the rest.

What is –die-on-term?

By default uWSGI maps the SIGTERM signal to “a brutal reload procedure”.

However, Upstart uses SIGTERM to completely shutdown processes. die-on-term inverts the meanings of SIGTERM and SIGQUIT to uWSGI.

The first will shutdown the whole stack, the second one will brutally reload it.

Хостинг Python проекта — настройка uWSGI по шагам: 4 комментария

А пост мог бы получиться отличный. Но неясно для носителей какого языка он писан. 50 / 50? Время позднее и в английские буковки вчитываться лень, а перевести ты не удосужился. С таким же успехом можно было кинуть ссылку на документацию.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *