разработчик
2,4
рейтинг
21 ноября 2012 в 11:30

Разработка → Боевой сервер для Django-приложения: Ubuntu Server 10.04 LTS + django 1.4 + nginx + gunicorn из песочницы

Многие учебные пособия по разработке на Django раскрывают как быстро получить работающий отладочный сервер (python manage.py runserver), а вопрос развертывания в боевом режиме часто остается нераскрытым или освещаются далеко не самые простые и эффективные методы.
Ниже я расскажу о об одном из способов развернуть сайт на Django в боевом режиме, начиная от выбора хостинга, заканчивая развертыванием веб-сервера. Таким образом статья может быть полезна тем, кто освоил разработку на базе Django, но не имеет опыта развертывания серверов. Мой способ один из многих, но он достаточно прост, эффективен в работе и легок в поддержке. Используем VPS-хостинг, Ubuntu 10.04, nginx, gunicorn.



Оглавление




Структура проекта


Для дальнейшего повестования необходимо рассказать про структуру развертываемого проекта:
- myproject/ - корень проекта, обратите внимание, что это не корень исходников проекта;
    - env/ - вируальное окружение, создаваемое при помощи virtualenv;
    - src/ - папка с иходниками, ее удобно добавить в пути IDE, для того, чтобы обращаться к пакету myproject по имени;
        - myproject/ - корень исходников проекта, должна быть знакома Django-программистам;
            - __init__.py
            - settings.py
            - manage.py
            - urls.py
            - myapp1/
            - myapp2/
             ...
    - static_content/ - папка для файлов, которые раздает веб-сервер первого эшелона (у нас - nginx), будучи параноиком, я боюсь передавать веб-серверу папку, содержащую исходники проекта;
        - static/ - статические файлы проекта (то что храним в репозитории);
        - media/ - media-файлы, то что создается сайтом в ходе его функционирования;
    - docs/ - тут лежат полезные документы, комментарии, примеры конфигов;
    - logs/ - папка, куда складываю логи, касающиеся работы сайта;
    - pids/ - тут pid-файлы.

На первый взгляд глубина вложенности исходников может показаться избыточной. Однако мой опыт показывает, что издержки на работу при такой глубине невелики, а достоинства большей структурированности значительны.

О хранении исходников
В рамках статьи не раскрывается вопрос хранения исходников проекта, поскольку выбор, организация, настройка доступа репозитория — отдельная тема для статьи.


Хостинг


Для себя я давно выяснил, что наиболее удобный хостинг для django — это VPS хостинг. Перепробовав несколько VPS-хостингов, я остановился на наиболее приемлемом в соотношении цена/качество — FirstVDS. Я пользуюсь тарифом за 400 рублей в месяц — 1500 MB RAM, 24000 MB HDD. Но сначала обходился тарифом за 150 рублей (в этом случае нужно будет научить некоторые приложения потреблять меньше ресурсов).
Итак, для того, чтобы начать нужно заказать и оплатить VPS, выбрав при этом тип виртуализации OpenVZ — неполная имитация физической машины, но для наших задач вполне достаточная, стоит заметить, что при такой виртуализации за те же деньги памяти дают больше, пригодится для memcached. В качестве операционной системы рекомендую выбирать Ubuntu Server 10.04 LTS#. Доступна также и Ubuntu Server 12.04 LTS, мне без особого труда удалось ввести ее в строй, однако шаблон на хостинге появился недавно, да и специалисты поддержки хостинг-провайдера не рекомендуют пока ее ставить на боевые сервера. Сейчас использую ее только на тестовом сервере.

Альтернативные Ubuntu Server операционные системы для хостинга
Наверняка найдутся адвокаты более стабильных систем для хостинга: FreeBSD, Debian, RedHat, CentOS. Не буду ввязываться в холивар. Замечу лишь, что мой опыт показывает, что для разработки на Django, часто требуются довольно новые версии пакетов и приложений. На перечисленные системы эти пакеты встают после подпирания множеством костылей, что, в итоге, сводит на нет ее надежность. В Ubutnu же новые версии пакетов принимаются в репозитории гораздо быстрее.


После заказа и оплаты на почту приходит SSH-доступ, теперь можно приступать к настройке операционной системы.

Ubuntu server


Получив доступ, я, первым делом, обновляю систему, затем отключаю root-доступ по SSH.
Подключиться по SSH в Windows можно широкоизвестной программой Putty, но я использую ее более “накрученную” модификацию — kitty. В качестве IP-адреса сервера вводим высланный хостером адрес, подключаемся, вводим root в качестве user и пароль при запросе.
Для подключения в Линукс-подобных системах используем родной терминал (Terminal, Konsole, etc.), набрав в нем нехитрую команду:
ssh root@1.2.3.4

где 1.2.3.4 — IP-адрес, высланный хостером, при запросе вводим пароль, высланный хостинг-провайдером.
Первым делом сменим пароль рута, паранойи ради:
passwd

по запросу вводим новый пароль дважды, генерировать и хранить советую в KeePassX, не стесняйтесь сделать его посложнее (>20 символов), использовать его почти не придется.
Обновляем пакеты в системе:

apt-get update
apt-get upgrade

Добавляем пользователя, от лица которого будем развертывать сервер:
adduser myuser

можно ничего не вводить кроме пароля, но лучше его придумать посложнее
Теперь понадобится редактор для правки конфигов, я предпочитаю nano:
apt-get install nano

Добавляем пользователю права исполнять команды от имени root (sudo):

nano /etc/sudoers
# находим строку
root    ALL=(ALL:ALL) ALL
# сразу после нее вставляем
myuser    ALL=(ALL:ALL) ALL

Теперь отключаем возможность пользователю root логиниться по SSH (делать необязательно, мера безопасности):

nano /etc/ssh/sshd_config
# ищем
PermitRootLogin yes
# меняем на
PermitRootLogin no

после этого я перезагружаю машину, чтобы убедиться, что все прошло как надо:
reboot

Спустя минуту можно логиниться как myuser (или можете предварительно проверить, что логин рутом больше не работает):
ssh myuser@1.2.3.4


Теперь я ставлю ряд системных пакетов, необходимых для работы Django-приложения и инфраструктуры:
sudo apt-get install gcc mysql-server python-mysqldb memcached mercurial python-profiler w3m python-setuptools libmysqlclient-dev git-core python-dev rabbitmq-server supervisor nginx

Давайте разберем, что есть что:
  • gcc — компилятор C, C++, чего-то еще до кучи, определенно понадобится для сборки некоторых пакетов;
  • python-setuptools — установка команды easy_install, понадобится только для установки virtualenv, дело в том, что из системных пакетов virtualenv устанавливается не последней версии, с чем возникает ряд раздражающих проблем;
  • mysql-server — из названия ясно, что это MySQL-сервер, понадобится нам, раз мы собираемся поднимать сервер баз данных на хосте веб-приложения;
  • libmysqlclient-dev — этот пакет понадобиться для того, чтобы собрать интерфейс доступа к MySQL для python;
  • python-dev — API python’а, определенно понадобится для сборки некоторых пакетов;
  • supervisor — это программа — контроллер демонов, понадобится для приручения веб-сервера и, возможно, ряда других программ;
  • nginx — веб-сервер nginx, выражаю свою признательность Игорю Сысоеву;
  • rabbitmq-server — необязательно, AMQP-сервер, пригодится, если потребуется использовать celery;
  • memcached — необязательно, известная реализация кеша в оперативной памяти;
  • git-core — необязательно, клиент для системы контроля версий git, потребуется, если нужные пакеты хранятся в git-репозитории;
  • mercurial — необязательно, клиент для системы контроля версий mercurial (hg), потребуется, если нужные пакеты хранятся в mercurial-репозитории.


Развертывание проекта


Для развертывания воспользуемся виртуальным окружением, при помощи инструмента virtualenv.
В предыдущей главе мы установили полезную утилиту easy_install, с помощью которой установим теперь virtualenv последней версии:
sudo easy_install virtualenv

Примечание. Я намеренно не ставил pip глобально, чтобы не было случайных конфликтов с ним у pip’ов в виртуальных окружениях.
Теперь можно приступить к развертыванию проекта. Для начала нужно разместить его где-то в домашней директории, пусть это будет:
/home/myuser/web/myproject

Я пользуюсь системой контроля версий git. Но вы можете добиться этого простым копированием по SCP. В Windows можно использовать WinSCP, в линуксах файловые менеджеры поддерживают формат адреса sftp://myuser@1.2.3.4, как вы наверное догадались, в качестве аутентификационных используются данные для доступа по SSH.
В моем проекте в корне лежит файл для сборки виртуального окружения — build_env.sh:
#!/bin/bash
echo $0: Creating virtual environment
virtualenv --prompt="<myenv>" ./env

mkdir ./logs
mkdir ./pids
mkdir ./db
mkdir ./static_content
mkdir ./static_content/media

echo $0: Installing dependencies
source ./env/bin/activate
export PIP_REQUIRE_VIRTUALENV=true
./env/bin/pip install --requirement=./requirements.conf --log=./logs/build_pip_packages.log

echo $0: Making virtual environment relocatable
virtualenv --relocatable ./env

echo $0: Creating virtual environment finished.

и файл requirements.conf, который содержит пакеты, необходимые для работы приложения:
django
git+git://github.com/sehmaschine/django-grappelli.git#egg=django-grappelli
git+git://github.com/django-mptt/django-mptt.git#egg=django-mptt
git+git://github.com/krvss/django-social-auth.git#django-social-auth
git+git://github.com/gabrielhurley/django-wymeditor.git#django-wymeditor
git+git://github.com/jtauber/django-mailer.git#django-mailer
git+git://github.com/tweepy/tweepy.git#tweepy
django-celery
django-debug-toolbar
django-pdb
python-memcached
MySQL-python 
xlrd
unidecode
anyjson
gunicorn
pillow
south
fabric
requests
xlwt

Это возможный набор пакетов, как-нибудь расскажу подробнее про некоторые из них, но мы не углубляемся в аспекты разработки в этой теме.
Итак, после запуска в папке проекта /home/myuser/web/myproject:
./build_env.sh

устанавливается виртуальное окружение для работы нашего сервера.
Теперь нужно позаботиться о создании базы данных. В наших проектах мы используем MySQL. Запускаем консоль MySQL:
mysql -uroot -pROOTPASSWORD

где создаем базу и пользователя:
CREATE DATABASE myproject CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'myproject'@'localhost' IDENTIFIED BY 'USERPASSWORD';
GRANT ALL PRIVILEGES ON myproject.* TO ‘myproject'@'localhost';

теперь настройки доступа можно внести в файл настроек проекта (settings.py или local_settings.py).
Если у вас есть дамп базы — вы знаете, что делать. Если нет, то создаем в ней схему и необходимые данные:
cd ~/web/myproject              # возвращаемся в папку проекта
source env/bin/activate         # активируем виртуальное окружение
python manage.py syncdb    # синхронизируем модели с базой данных

теперь соберем статические файлы:
python manage.py collectstatic

На этом приложение готово к запуску.

Настройка веб-сервера Nginx


Для настройки веб-сервера Nginx нужно разместить конфиг myproject.conf (суффикс должен быть .conf) в папке /etc/nginx/sites-available/.
Создать и отредактировать файл можно в консоле SSH через nano:
sudo nano /etc/nginx/sites-available/myproject.conf

затем вставляем содержимое примера ниже (Shift+Insert), исправляем под свои нужды, сохраняем (Ctrl+O), выходим (Ctrl+X).
Пример содержания файла myproject.conf:
upstream myproject.ru {
    server localhost:12345 fail_timeout=0;
}

server {
    listen 80;
    server_name  www.myproject.ru;
    rewrite ^/(.*) http://myproject.ru/$1 permanent;
}

server {
    listen 80;
    client_max_body_size 4G;
    server_name myproject.ru;
    access_log  /home/myuser/web/myproject/logs/myproject.access.log;
    keepalive_timeout 5;

    root /home/myuser/web/myproject/static_content;
    
    location / {
        proxy_pass http://myproject.ru;
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /home/myuser/web/myproject/static_content/static/html;
    }

    location ~ ^/(static|media)/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        if (!-f $request_filename) {
            proxy_pass http://myproject.ru;
            break;
        }
     }
}
Попробуем разобраться в общих словах, что здесь к чему.
В данном примере upstream — сокет localhost:12345, в который будем пересылать все запросы, которые не удовлетворяют следующим url:
/static/* — статические файлы сайта;
/media/* — медиа-файлы, файлы, которые создаются в процессе функционирования сайта;
На этом сокете мы повесим на прослушивание наш gunicorn в следующей части статьи. Имя апстрима, теоретически, выбирается произвольно, однако я сталкивался с проблемами, в случае, если имя апстрима отличалось от доменного имени сайта (не помню текста ошибок Django, чтобы описать подробнее).

Еще интересные части конфига:
редирект с поддомена www.myproject.ru на myproject.ru, можете сделать наоборот, если вам больше нравится;
обработка ошибок 5XX орагнизована выдачей статического файла 500.html. Получить такой файл довольно просто: заставить сайт показать страницу 404, сохранить в браузере как 500.html и отредактировать текст ошибки;
в случае, если статический файл не найден, запрос направляется gunicorn’у, чтобы тот мог выдать стандартную ошибку 404.

После того, как файл конфига размещен где следует (можно проверить командой cat /etc/nginx/sites-available/myproject.conf), нужно проставить на него симлинк:
sudo ln -s /etc/nginx/sites-available/myproject.conf /etc/nginx/sites-enabled/

и перезапустить nginx:
sudo service nginx restart


Настройка gunicorn и supervisor


При развертывании проекта мы установили пакет gunicorn, теперь мы используем его для формирования динамичеких HTTP-ответов (HTTP-response) Django-приложением. Сам gunicorn умеет принимать запросы и формировать ответы на них, однако нужно поддерживать сам gunicorn запущенным, например стартовать при перезапуске системы, это мы поручим специализирующейся в этом программе supervisor.
Заметьте, что разработчики gunicorn крайне не рекомендуют ставить его на линию фронта, а поручить прием запросов от пользователей специализированным серверам, например nginx, как это делаем мы.
Итак, создаем в папке /etc/supervisor/conf.d/ файл myproject.conf следующего содержания:
[program:myproject]
command=/home/myuser/web/myproject/env/bin/python /home/myuser/web/myproject/src/myproject/manage.py run_gunicorn --bind=localhost:12345 --workers=3 --pid=/home/myuser/web/myproject/pids/gunicorn.pid --log-file /home/myuser/web/myproject/logs/gunicorn.log
directory=/home/myuser/web/myproject/src/myproject
umask=022
autostart=true
autorestart=true
startsecs=10
startretries=3
exitcodes=0,2
stopsignal=TERM
stopwaitsecs=10
user=myuser

Заметьте, что в параметрах gunicorn’у мы передаем для прослушки тот же порт (в нашем примере 12345), что указывали в конфиге nginx’а. Количество рабочих процессов установлено в значение 3, подбирал этот параметр субъективно для одного из сайтов, исходя из своих нагрузок, и пока не могу порекомендовать какое-либо значение.
После того как конфиг размещен в нужной папке (можно проверить запуском cat /etc/supervisor/conf.d/myproject.conf) нужно перечитать файл либо просто перезапустить supervisor, я использую второй вариант для надежности:
sudo supervisorctl reload

проверить успешность запуска можно командой:
sudo supervisorctl status

в случае успеха статус процесса myproject через несколько секунд станет RUNNING.

Устранение проблем


perl: warning: Setting locale failed.
С самого начала работы, при вводе команд, система начинает выдавать warning:
perl: warning: Setting locale failed. 
perl: warning: Please check that your locale settings:
решается добавлением правильной локали:
locale-gen ru_RU.UTF8

по мотивам: http://askubuntu.com/questions/76013/how-do-i-add-locale-to-ubuntu-server


sudo: must be setuid root
При первом применении sudo из-под нового пользователя возможна ошибка:
sudo: must be setuid root

решается например так:
chmod 4755 /usr/bin/sudo



E: Unable to correct problems, you have held broken packages.
при установке некоторых пакетов в Ubuntu 12.04 (например python-dev или libmysql-dev) возможна ошибка:
libc6-dev : Depends: libc6 (= 2.15-0ubuntu10.2) but 2.15-0ubuntu10+openvz0 is to be installed
E: Unable to correct problems, you have held broken packages.
Для ее решения достаточно модифицировать файл /etc/apt/preferences.d/99ovz-libc-pin:
заменив
libc-bin libc6

на
libc-bin libc6 libc6-dev libc-dev-bin



Couldn't open /dev/null: Permission denied
При создании пользователя может возникать ошибка:
Couldn't open /dev/null: Permission denied

решал так:
sudo chmod 666  /dev/null

не знаю, насколько это корректно, но я опасностей не увидел.


Заключение


Отметим положительные моменты такого развертывания:
  • Развертывание решения на VPS, виртуальная машина дает практически неограниченные возможности в администрировании.
  • Независимость nginx от gunicorn, как это часто предлагается при использовании Apache и mod_python, например. В частности довольно легко подменить, например для отладки, gunicorn разработческим сервером:
    sudo supervisorctl stop myproject
    python manage.py runserver localhost:12345 # из папки с исходниками
    

    теперь nginx будет передавать запросы на сервер разработчика, даже не узнав про изменения.
  • Nginx в качестве раздавальщика статических файлов признан одним из лучших, может даже лучшим.
  • virtualenv позволяет легко и непринужденно изолировать виртуальные окружения разных проектов друг от друга. В наше время издержки дискового пространства несравнимо дешевле возни с конфликтами версий пакетов.
  • gunicorn под контролем supervisor значительно удобнее и надежнее способов запуска gunicorn под контролем скриптов в /etc/init.d/ и некоторых других способов запуска, так как дает способ мониторинга запущенных программ, заботливо перезапускает программы в случае сбоев.

В сатье расмотрен лишь один из множества вариантов развертывания Django-приложения, я пришел к нему путем многих проб и ошибок. Мои рекомендации не претендуют на истину в последней инстанции. Более того, буду рад любой конструктивной критике.

Полезные ссылки


  1. FirstVDS — дешевый VPS-хостинг, по ссылке заказ на четверть дешевле.
  2. Putty и Kitty — SSH-клиенты под Windows.
  3. WinSCP — SCP-клиент под Windows, не нужно поднимать FTP-сервер, просто используйте имеющийся SSH-аккаунт.
  4. KeePassX — утилита хранения паролей, кроссплатформенная.
  5. Ubuntu LTS — политика выпусков релизов Ubuntu Long Term Support.
  6. Ubuntu Security — настройка для параноиков для десктопа, но что-то можно почерпнуть для сервера.
  7. Django Deployement — другие способы развертывания сайтов на Django.
  8. virtualenv — использование virtualenv.
  9. Nginx — много интересного о настройке nginx.
  10. Supervisor+gunicorn — об использовании gunicorn через nginx.
Алексей @alekseyspb
карма
36,0
рейтинг 2,4
разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (41)

  • 0
    Убунту можно и 12.04 использовать, она ведь ЛТС
    • 0
      Можно, но как я понял, сейчас, у хостера она поставляется не с родной версией ядра, что рождает много рисков.
      И раз зашел разговор, я об этом писал в топике:

      Доступна также и Ubuntu Server 12.04 LTS, мне без особого труда удалось ввести ее в строй, однако шаблон на хостинге появился недавно, да и специалисты поддержки хостинг-провайдера не рекомендуют пока ее ставить на боевые сервера. Сейчас использую ее только на тестовом сервере.

  • +2
    Теперь отключаем возможность пользователю root логиниться по SSH (делать необязательно, мера безопасности)


    Если не секрет, какую именно безопасность обеспечивает данная мера? Увеличивает количество попыток подбора пары логин+пароль с бесконечного до бесконечного?
    • +1
      Если не запрещать подключение по SSH от root, количество попыток подбора пары «логин+пароль» снижается до количества подборок пароля, и весьма наивно полагать, что оно равняется бесконечности. Кроме того, если будет найдена уязвимость в ssh-сервере или связанных с ним библиотеках, позволяющая, скажем, заходить без пароля, то будет несоизмеримо лучше, если никто не сможет провернуть этот фокус от рута. Безопасность должна быть эшелонированной.
      • 0
        Ну раз эшелонированной, тогда myuser ALL=(ALL:ALL) ALL это уж слишком просторно.
        • 0
          Да, некрасиво, но это уже вопрос к автору.
          • 0
            Да, думаю, что это недоработка. При разработке своего рецепта я исходил из опыта, пытаясь решить 80% проблем за 20% усилий.
      • 0
        С заходом без пароля забыл, спасибо.
      • +1
        А не лучше отключить вход по паролю через SSH совсем (и для рута, и для пользователей)? SSH с ключами и удобнее, и безопаснее.
        • 0
          Конечно, лучше. Естественно, если ключи надежно хранятся и готовы к использованию в любой момент.
          • 0
            И ключи не простые а с паролями
            • 0
              Если уж пошел разговор о безопасности — то надо использовать еще до кучи и knockd с нестандартными портами и тайм-аутами, но в рамках статьи это, ИМХО, избыточно уже.
  • +5
    А почему именно gunicorn, а не, скажем, uwsgi?
    • +1
      или mod_wsgi или cherrype или…
      Это тема для отдельной статьи

      Пробовал как-то apache mod_wsgi vs nginx uwsgi на своем не большом проекте — разницы не было, поэтому оставил apache
    • 0
      Видимо ответ тот же — личные предпочтения.
  • +1
    В зависимостях лучше всегда указывать версии (причем даже ==, а не >= или <=) и коммиты в git-репозиториях. Сначала кажется, что это не очень важно, что вроде следишь за обновлениями и поправишь код, если что. Но когда через год проект перестает работать из-за того, что какой-то там пакет обновился, половина программистов, которые над кодом работали, занята чем-то другим, а другая уже и не помнит, о чем там речь была… Короче, лишняя ненужная работа получается.

    supervisord еще можно в виртуаленв ставить (pip install supervisord): если на сервере несколько проектов, то у каждого будет свой supervisord, и sudo не нужно будет дергать для перезапуска.
    • 0
      kmike, спасибо, за конструктивную критику, у меня стояла задача поддержать версионность пакетов, но из-за приоритетов так и не добрался до нее. Кстати, задача должна решаться просто, так как pip, с некоторых пор научили выдавать в том же формате список зависимостей с указанием версий.
      • 0
        pip freeze — да, но там разные «но» есть (с -e пакетами freeze может не справиться + после pip install -U уже не выяснить правильные зависимости). Проще сразу версии указывать явно, и обновления версий в VCS фиксировать (т.к. версии сторонних пакетов, по сути, тоже ведь код проекта определяют). Это не критика, дополнения просто, описано все хорошо.
  • 0
    Интересно узнать чем хорош gunicorn, сейчас я использую для подобных целей tornado, который так же запускает django проекты.
    Но при этом в моей связке есть особенность, при который торнадо перестаёт отвечать, но не падает и supervisor не перезагружает его. Может gunicorn мне подойдёт.
    • 0
      Не пробовал tornado, вполне возможно, что проект хорош. Мне проект gunicorn нравится за счет того, что был портирован из зарекомендовавшего себя unicorn из мира ROR. Если приложение виснет — смотрите логи.
  • 0
    Двум предыдущим отвечу: uwsgi не страдает (за 2 года не заметил) проблемами «перестаёт отвечать», а для перезапуска (в режиме императора) достаточно сделать touch конфига.
    projects.unbit.it/uwsgi/wiki/Emperor
  • –3
    Чем Nginx + FastCGI не угодил?)
    • +1
      Он имеет право на жизнь, как все остальные способы развертывания Django-приложений. В статье не утверждается что мой способ самый лучший.
      • 0
        Странно, что совершенно безобидный вопрос по теме заминусовали. К тому же, я кажется нигде и не затграгивал тему единственно верных решений.

        Хотелось узнать почему вы выбрали именно такой спсобо для развертывания Django-приложений, но увы.
        • 0
          Поставил минус, объясню почему. Каждое обсуждение способа развертывания питоньих проектов неизбежно скатывается в fastcgi vs uwsgi vs gunicorn vs apache mod_wsgi vs ..., как будто этот вопрос имеет хоть какое-то значение. Ну да, они все немного отличаются друг от друга по фичам и по способу настройки, но они не сделают магическим образом сайт быстрее или надежнее.

          Значение имеет не набора букв в описании веб-стека, а то, как все настроено; чтоб все настроить хорошо, нужно понимание того, как все работает, и того, чего же хочется получить-то. Интернетные советы «uwsgi быстрее mod_wsgi», как мне кажется, от этого понимания отдаляют, а не приближают — вместо того, чтоб разобраться в проблеме, люди начинают верить в наборы букв (иногда еще обосновывая свою веру идиотскими бенчмарками хелло-вордов).

          Кстати, мне кажется (судя по тому, что коммент про uwsgi заплюсован), что еще вам минусов понаставили из-за того, что в конкретный набор букв (fastcgi) не верят.
          • 0
            Другое дело. Спасибо.
  • 0
    Интересно насчет хостинга FirstVDS, который вы рекомендуете.
    Он сильно дешевле других. Не страдает ли качество?
    • +1
      Года три назад очень страдало.
    • 0
      Сейчас работает два приносящих прибыль интернет-магазина. Не жалуемся на хостера уже пару лет.
  • +2
    Хочется отдельно сказать спасибо автору за краткое и емкое вступление, за оглавление и четкую структуру статьи.
    • 0
      Спасибо, я старался сделать статью полезной.
  • 0
    Присоединяюсь к отзыву о FirstVDS — тоже был приятно удивлён пол года назад.

    По теме статьи:
    * Вы указали fabric в зависимостях, так где же fabfile? Зачем какие то build_env.sh когда есть fabric?
    * В зависимостях у Вас south, значит что нужно делать syncdb с миграциями
    python manage.py syncdb --migrate
    


    Из полезного по теме развёртывания и не только могу проделожить ознакомиться с lincolnloop.com/django-best-practices/ и с их темплейтным Django-проектом
    github.com/lincolnloop/django-layout. Про деплой — обратите внимание на их fabfile. «Лучше день потерять, а потом за пять минут долететь» (с)

    Мы для себя этот шаблонный проект несколько переосмыслили, добавили туда HTML5 Boilerplate сразу скрещенный с Bootstrap, ещё немного перчику — и получился приличный шаблон для быстрого старта.
    • 0
      уже ненужно.
      теперь

      manage.py syncdb (sync для тех app, где нет south и проверка south что вобще делать собираемся)
      manage.py migrate (собсно migrate для south)
    • 0
      fabric — отдельная тема, активно используем, напишу, если время найдется.
      по поводу south — у нас применяется ряд мер, в том числе, по залитию дампа базы, по syncdb домыслил, уточню, спасибо.
    • +1
      Спасибо тебе, добрый человек, за ссылки.
  • 0
    как раз таки нужно
    команда
    syncdb --migrate
    выполняет syncdb у приложений, которые не по south и migrate у тех, которые под south
  • 0
    Время идёт, а статья актуальна
    • 0
      Спасибо, рад если помог вам.
      • 0

        Спасибо вам, статья всё еще актуальна.

        • 0
          Спасибо, рад, конечно, что статья еще помогает, но с тех пор закрепились Ansible, Docker, Амазон предлагает вообще забыть о том как запускать веб-приложения.

          Статья перешла в раздел «интересно сделать самому», в реальных приложениях сегодня делают по-другому.
    • 0
      Не актуальна. Надо пользоваться системой управления конфигурациями.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.