coub css express.js freeware git jquery laravel links linux macos mysql node.js php PostgreSQL python task1 ubuntu vim virtualbox анекдот игры интересно музыка стихи цитаты

Django + Gunicorn + virtualenv + nginx #2 November 29, 2013
Напишу ещё раз на всякий случай.
Я не настоящий сварщик! То есть не проф. python программист. Я только учусь!

Итого успехи у меня не большие к этому моменту. Я поиграл с flask-ом и поленившись всерьез добраться до SQLAlchemy взял Django как фреймворк пока. Пока это не было важно. Я хотел разобраться как устроена боевая серверная часть хотя бы на базовом уровне и кажется у меня получилось.
Суть примерно такая:
  • Впереди стоит nginx который форвардит соединения для хоста на порт приложения
  • За nginx стоит Gunicorn (Python WSGI HTTP Server)
  • За Gunicorn уже само приложение на Django
  • Все python компоненты, необходимые для работы приложения, собираются при помощи virtualenv + pip

Теперь чуть больше порядка.
  1. pip - это инструмент для установки и управления python-компонентами. То есть эта штука позволяет нам грубо говоря ставить/удалять/искать/создавать разные пакеты с указанной версией. Эдакий питоний apt-get или npm для node.js. Как он устанавливается и работает можно почитать на офсайте.
  2. virtualenv - инструмент для создания "виртуальной среды" для выбранного приложения. По-простому говоря у вас на одном сервере живет несколько приложений которые требуют разные версии одного и того же python-компонента. Обязательно разные версии. Как быть, ведь глобально можно установить ровно одну версию. Тут как раз придет на помощь virtualenv. В общем тоже что и в node.js есть компоненты установленные глобально, а есть установленные специально под приложение и все это барахло можно контролировать. В разных доках и туториалах по python разработке умные дядьки настоятельно рекомендуют использовать virtualenv и я тут могу только с ними согласиться. Смысл очевиден. Ставится просто:
    sudo pip install virtualenv
    
    Базовое использование совсем не сложно
    # переходим в папку нашего проекта
    cd ~/project-folder
    # инициализируем вирт. среду (название среды может быть любым, у меня это ENV)
    virtualenv ENV
    # теперь внутри папки с нашим проектом будет создана папка ENV 
    # с инициализированной виртуальной средой внутри
    # теперь активируем эту вирт. среду
    source ./ENV/bin/activate
    # обратите внимание строка приглашения bash будет дополнена названием среды
    # у меня в примере она выглядит вот так: (ENV)luke@tatuin:~/project-folder$
    # теперь ставим в эту вирт среду нужные компоненты
    pip install Django
    pip install gunicorn
    pip install mysql-python
    # и так далее.. все что установлено можно посмотреть вот так
    pip list
    # для выхода из виртуальной среды нужно просто вызвать
    deactivate
    
    В общем суть в том что virtualenv в активированном состоянии подменяет переменные в env (наберите в консоли env чтобы посмотреть текущие переменные окружения), отвечающие за размещение пакетов и бинарников, после деактивации все возвращается обратно, как было.
  3. Как сделать болванку приложения на Django можно почитать на офсайте. Про это я сейчас писать ничего не буду, тут нет ничего необычного, все как в мануале. Будем считать что приложение у меня есть.
  4. Сейчас у нас есть приложение и настроенная среда для приложения. Папка с приложением у меня сейчас выглядит вот так:
    domain
    ENV
    manage.py
    manage.pyc
    requirements.txt
    run-dev.sh
    run-prod.sh
    static
    templates
    test1
    
    ENV - папка с вирт. средой, domain - приложение проекта test1 (примерно так выглядит обычная структура django-приложения). Соответственно, чтобы запустить отладочную версию проекта достаточно запустить (при активированном virtualenv)
    python manage.py runserver
    
    Ну и чтобы запустить боевую версию на gunicorn-e (при активированном virtualenv) делаем так
    gunicorn test1.wsgi:application -b 127.0.0.1:8800 --env FOO=VAL
    
    Здесь мы биндим наше приложение на IP и порт. Через --env передаем переменную окружения (см. мануал по gunicorn) чтобы сообщить что-то приложению, что мы боевая версия например или номер генератора на котором будем работать, да что угодно в общем. Вообще запуск gunicorn можно отдельно конфигурировать в файл и читать все оттуда, это все есть на офсайте. В данном случае, для Django, запуск выглядит не совсем тривиально, с простыми приложениями это немного иначе выглядит.
  5. Ну и в конце nginx, через который мы завернем хост на наше приложение
    server {
        listen   80;
        server_name lest1.loc;
    
        proxy_set_header Host $http_host;
    
        location / {
            proxy_pass http://127.0.0.1:8800;
        }
    }
    
    На этом месте данных должно быть достаточно чтобы запустить приложение в боевом режиме. У Django ещё куча доп. внутренних настроек для отладки, но это уже другая история.
  6. Что осталось. Осталось понять как сохранять состояние среды окружения и как его восстанавливать обратно. Сохранить состояние можно в текстовый файл вот так
    pip freeze > requirements.txt
    
    Название файла может быть любым, по сути главное там формат. Загляните внутрь. Внутри будет содержимое вида
    Django==1.6
    MySQL-python==1.2.4
    argparse==1.2.1
    gunicorn==18.0
    wsgiref==0.1.2
    
    Теперь коммитим это в нашу систему контроля версий и когда нужно будет восстановить состояние проекта - создаем вирт. среду через virtualenv, активируем её и выполняем установку пакетов из сохраненного файла состояния вирт. среды. Все вместе будет выглядеть вот так:
    cd proj-folder
    virtualenv ENV
    source ./ENV/bin/activate
    pip install -r requirements.txt
    
    Pip считает данные о зависимостях из текстовика и установит в вирт.среду все что нужно. Если будет нужно что-то скачать, то он конечно попробует скачать сам. Ну, тут уже все понятно. Пока это все. Надеюсь следующая пауза не будет длиннее.
REM: для установки mysql-python может понадобиться установить библиотеку
sudo apt-get install python-dev
sudo apt-get install libmysqlclient-dev
python task1