12/01/2013

Django, uWSGI, nginx deployment (Ubuntu 12.04)


В этой статье я хочу рассказать о том как с нуля развернуть простой (в данном случае очень простой) Django продакшн сервер.


Для начала скажу что разворачивать буду на Ubuntu 12.04.
То, что должно быть и было на момен написания статьи в моей системе (напоминаю, что версии пакетов могут сильно разниться в зависимости от того, сколько лет спустя вы открыли эту статью). И так список моих пакетов по возможности с версиями:
nginx 1.1.19
build-essential
python 2.7.3
python-dev
python-virtualenv
Про то что и какое стоит в виртуальной среде питона (а именно в ней по всем законом фэн-шуя мы и будем разворачивать Django проект), расскажу чуть позже.

Постараюсь описать все подводные камни которые встретились на моём пути, в остальных случаях слабаки могут уповать на не соответствие версий пакетов, более упёртые могут копать документацию или просторы интеренета. Да, забыл, если что можно писать вопросы в комменты либо мне на почту.

Теперь всё попорядку. Специально буду писать всё как у меня, чтоб новички могли повторить в точности.

1. Создаем виртуальную среду Python
:~/prod$ pwd
/home/igor/prod
В дериктории проектов (у меня это директория /home/igor/prod) создаем директорию для нашего проекта и сразу переходим в неё:
:~/prod$ mkdir mydjango && cd mydjango
Создаём непосредственно виртуальную среду:
:~/prod/mydjango$ virtualenv --no-site-packages .env

2. Cтавим в виртаульную среду  django, uwsgi:
:~/prod/mydjango$ .env/bin/pip install django==1.6
:~/prod/mydjango$ .env/bin/pip install uwsgi==1.9.20

3. Создаем django проект
Создадим django проект с классичским именем mysite
:~/prod/mydjango$ .env/bin/django-admin.py startproject mysite
После чего у вас должна появиться директория с вложенными в неё каталогами django проекта.

Здесь нужно дать небольшое теоретическое пояснение о том как взаимедействуют все компоненты цепочки:

the web client (web browser)  <-> nginx <-> the socket (unix socket) <-> uWSGI <-> Python

Сокет - это компонент (представляет из себя простой файл) который позволяет взаимодействовать веб-серверу (nginx) c протоколом uWSGI, который в свою очередь является связующим звеном с Python приложением.

4. Создаём сокет
:~/prod/mydjango$ touch /var/tmp/mysite.sock

5. Создаём конфигурацию для nginx
Создадим файлы для логов
:~/prod/mydjango$ cd mysite && mkdir logs && touch logs/access.log logs/error.log logs/uwsgi.log
Также нам понадобится uwsgi_params файл который можно скопировать из /etc/nginx/uwsgi_params
:~/prod/mydjango/mysite$ cp /etc/nginx/uwsgi_params uwsgi_params
или из репозитория https://github.com/nginx/nginx/blob/master/conf/uwsgi_params и поместить его в директорию нашего django проекта (/home/igor/prod/mydjango/mysite/uwsgi_params).
Создадим файл конфигурации для nginx:
:~/prod/mydjango/mysite$ sudo touch /etc/nginx/sites-available/mysite.conf
с таким содержимым:
# mysite.conf

# configuration of the server
server {
    # the port your site will be served on
    listen      80;
    # the domain name it will serve for
    server_name 127.0.0.1; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    access_log /home/igor/prod/mydjango/mysite/logs/access.log;
    error_log /home/igor/prod/mydjango/mysite/logs/error.log;
    root /home/igor/prod/mydjango/mysite;

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass unix:///var/tmp/mysite.sock;
        include     /home/igor/prod/mydjango/mysite/uwsgi_params; # the uwsgi_params file you installed
    }
}
После чего нужно создать ссылку на него в активных сайтах nginx:
:~/prod/mydjango/mysite$ sudo ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/mysite.conf
и удалить возможно уже существующие ссылки на конфигурации в которых выставлен слушающий 80-й порт.

6. Создаём конфигурационный файл для uwsgi протокола (*.ini)
:~/prod/mydjango/mysite$ touch uwsgi_params
с таким содержимым:
# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /home/igor/prod/mydjango/mysite
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path)
home            = /home/igor/prod/mydjango/.env

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /var/tmp/mysite.sock
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = false
daemonize       = /home/igor/prod/mydjango/mysite/logs/uwsgi.log

7. Запуск продакшена
Запускаем nginx
:~/prod/mydjango/mysite$ sudo /etc/init.d/nginx start
или перезапусаем, если был уже запущен
:~/prod/mydjango/mysite$ sudo /etc/init.d/nginx restart
После всего запускаем uWSGI в режиме демона:
:~/prod/mydjango/mysite$ sudo ../.env/bin/uwsgi --ini mysite_uwsgi.ini
Вот и всё, теперь по адресу 127.0.0.1 или localhost можно увидеть стандартную страницу Django проекта.

Столкнулся с проблемой запуска uWSGI в интерактивном режиме - nginx выдавал ошибку с кодом 502 bad gateway, а в режиме демона такого не возникает. Если есть идеи, предложения, решения - буду рад слышать любые комментарии.

Рекомендуемые ссылки:
http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html

Комментариев нет:

Отправить комментарий