Настройка сервера. Создаем и разворачиваем django-проект
This post is part of a series:
- Год облачного хостинга от Amazon — бесплатно
- Настройка сервера. Gitolite — хостинг git-репозиториев
- Настройка сервера. Создаем и разворачиваем django-проект
Содержание:
В предыдущей статье показывалось как поднять и настроить хостинг Git репозиториев на своем сервере. Ниже будет описано создание Django проекта, развертывание его на сервере и настройка авто-обновления кода.
Note
Все инструкции в этой статье приводятся для системы Ubuntu Oneiric, пользователь ubuntu.
Makesite
Настройка, развертывание и обновление сайтов — операции, требующие автоматизации. Есть множество утилит для этого, например Capistrano (ruby) или Fabric (python). В свое время эта задача встала и передо мной. Были определены следующие требования:
- В основе системы должны находится shell скрипты;
- Развертывание проекта должно производится одной командой;
- Элементарное обновление или удаление проектов;
- Каждый экземпляр проекта привязан к ветке репозитория;
- Настройки всех проектов могут быть заданы как глобально, так и в момент развертывания;
- Легкость настройки и создания шаблонов;
- Автономность уже развернутого проекта;
Беглый осмотр существующих решений привел к необходимости в очередной раз писать свой велосипед. В итоге на свет появился Makesite. Описание всех принципов его работы выходит за рамки данной статьи.
Основное его предназначение — автоматическое создание будущей структуры сайта. Файлов конфигурации сервера и скриптов обновления и перезапуска. Вы можете изменять и редактировать параметры этих файлов после развертывания.
Установка и настройка Makesite
Note
Данные действия выполняются на сервере
Для начала работы на нашем сервере потребуется установить и настроить Makesite. Рекомендуется проводить установку при помощи setuptools:
# Устанавливаем setup-tools
sudo apt-get install python-setuptools python-pip
# Устанавливаем makesite
sudo easy_install makesite
# Или при помощи Pip
sudo pip install makesite
Теперь нам необходимо решить в какой директории будут развернуты наши проекты и указать ее для Makesite. Обычно я использую /var/www. Чтобы не вводить этот путь при каждой операции, определим системную переменную $MAKESITE_HOME. Удобно сразу это сделать при помощи следующей команды:
# Создаем директорию для хранения наших будущих сайтов
$ sudo mkdir /var/www
# Выводим и проверяем настройки bash
$ makesite shell -p /var/www
# Записываем их в ваш ~/.bashrc
$ makesite shell -p /var/www >> ~/.bashrc
# Загружаем настройки для текущего сеанса
$ source ~/.bashrc
Создаем корневой файл конфигурации в указанной нами директории /var/www/makesite.ini.
Note
В примерах используется адрес созданного в предыдущих статьях AWS сервера: awsdemo.us.to.
[Main]
# Указываем источник получения кода проектов по умолчанию
# В данном случае будет использоваться созданный нами репозиторий
# Префикс 'git+' указывает Makesite на способ получения
# В настройках можно применять переменные, в данном случае будет
# производиться поиск репозитория по имени разворачиваемого проекта
src = git+git@awsdemo.us.to:%(project)s.git
# Доменное имя для создаваемых конфигураций сайтов
# Можно было сделать например так:
# domain = %(branch)s.%(project)s.us.to
# Но так как полученный нами бесплатный DNS не поддерживает Wildcard записи,
# поступим проще:
domain = %(project)s.us.to
# Режим деплоя (это всего лишь переменная которую можно использовать в шаблонах)
mode = dev
Создание этого файла необязательно, но он здорово упрощает развертывание. В любом случае у вас всегда есть возможность изменять конфигурации после развертывания.
Создание проекта
Note
Данные действия выполняются локально
Перейдем к репозиторию awsdemo на нашей локальной машине, который мы создали в прошлой статье и превратим его в Django-проект.
# Переходим в директорию нашего проекта
$ cd ~/Projects/awsdemo
# Создаем новый django-проект
$ django-admin.py startproject aws
# Переносим файлы из созданного проекта в наш репозиторий
$ mv aws/* . && rm -r aws
# Сохраняем изменения в git
$ git add .
$ git commit -m 'Start new django-project'
Теперь его надо подготовить к деплою.
Note
Файлы с исходным кодом Django-проекта можно найти по адресу: https://github.com/klen/klen.github.com/tree/master/_code/awsdemo
Подготовка Django-проекта к деплою
Note
Данные действия выполняются локально
Рекомендуется, но совсем необязательно, создавать в корневой директории проекта файл конфигурации Makesite с основными параметрами деплоя.
Создадим файл makesite.ini:
[Main]
# Шаблоны Makesite которые будут применятся для нашего сайта
# всегда есть возможность создать собственные шаблоны
# в том числе и в хранимые с исходниками проекта
template=virtualenv,django,uwsgi
Для шаблона virtualenv (он создает и обновляет при необходимости виртуальное окружение проекта) необходимо создать файл с зависимостями.
requirements.txt:
# Django
Django==1.3
Для шаблона uwsgi (он запускает наш проект с помощью uwsgi и nginx) необходимо создать файл определяющий наше wsgi-приложение.
wsgi.py:
#!/usr/bin/env python
from os import environ
from django.core.handlers.wsgi import WSGIHandler
environ['DJANGO_SETTINGS_MODULE'] = environ.get(
'DJANGO_SETTINGS_MODULE', 'settings')
application = WSGIHandler()
Следующее, что необходимо сделать это поправить settings.py изменив его следующим образом (включаем базу данных, интерфейс администрирования, определяем путь к STATIC_ROOT и правим urlconf):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'aws.db',
...
from os import path as op
DEPLOY_DIR = op.dirname(op.dirname(__file__))
STATIC_ROOT = op.join(DEPLOY_DIR, 'static')
...
ROOT_URLCONF = 'urls'
...
# Uncomment the next line to enable the admin:
'django.contrib.admin',
...
И последнее создадим фикстуру для создания первого пользователя initial_data.json (login: admin, pasword: admin):
[{
"model": "auth.user",
"pk": 1,
"fields": {
"username": "admin",
"first_name": "Darth",
"last_name": "Vader",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2000-01-01 00:00:00",
"groups": [],
"user_permissions": [],
"password": "sha1$bb19a$51b2bac8dd83c30e6cf6694bf3049241a14124ea",
"email": "admin@admin.admin",
"date_joined": "2000-01-01 00:00:00"
}}]
Наш проект готов к деплою.
Создание ключей для клонирования репозитория
Note
Данные действия выполняются на сервере
Деплоить будем из нашего репозитория. Чтобы это возможность появилась, надо или перенести свой приватный ключ на сервер или создать новый и дать на него доступ в gitolite-admin.
Я предпочитаю второй вариант:
# Переходим в нашу домашнюю .ssh директорию
$ cd ~/.ssh
# Создаем отдельный ключ для makesite (укажите makesite в имени файла)
# без паролей
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): makesite
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in makesite.
Your public key has been saved in makesite.pub.
# Копируем ключ в id_rsa
$ cp makesite id_rsa
$ cp makesite.pub id_rsa.pub
Полученный ключ надо подключить к нашему репозиторию, путем редактирования gitolite_admin (подробности в предыдущей статье). Вкратце ваш порядок действий:
- Скопировать ключ ~/.ssh/makesite.pub в gitolite-admin/keydir/makesite.pub (например при помощи scp)
- Обновить параметры доступа к awsdemo в файле gitolite-admin/conf/gitolite.conf (добавить строчку RW+ makesite)
- Сделать коммит с изменениями и пуш на сервер.
Теперь можно проверить работу с репозиторием на стороне сервера:
git clone git@awsdemo.us.to:awsdemo.git /tmp/aws
В случае успеха репозиторий должен быть скопирован с удаленного сервера иначе вы, что-то неправильно сделали с ключами.
Установка зависимостей
Note
Данные действия выполняются на сервере
Дадим команду Makesite на деплой нашего проекта:
makesite install awsdemo
Помните мы указали строку "src = git+git@awsdemo.us.to:%(project)s.git" в /var/www/makesite.ini, она говорит Makesite где получать исходники проекта. То есть вышеприведенная команда по факту транслируется следующим образом:
makesite install awsdemo --src git+git@awsdemo.us.to:awsdemo.git
Note
Makesite поддерживает установку из пути файловой системы, или git, mercurial (hg+), subversion (svn+) систем контроля версий
Вывод команды будет приблизительно таким:
Clone src: git+git@awsdemo.us.to:awsdemo.git -------------------------------------------- Cmd: /usr/bin/git clone git@awsdemo.us.to:awsdemo.git /tmp/tmpkWznFx/source remote: Counting objects: 12, done. remote: Compressing objects: 100% (9/9), done. remote: Total 12 (delta 1), reused 0 (delta 0) Receiving objects: 100% (12/12), done. Resolving deltas: 100% (1/1), done. Deploy templates: base,src-git,virtualenv,supervisor,nginx,uwsgi ---------------------------------------------------------------- Prepare template: base Prepare template: src-git Prepare template: virtualenv Prepare template: supervisor Prepare template: nginx Prepare template: uwsgi Check requirements ------------------ Cmd: sudo chmod +x /tmp/tmpkWznFx/service/*.sh Cmd: /bin/bash /tmp/tmpkWznFx/service/base_check.sh Cmd: /bin/bash /tmp/tmpkWznFx/service/virtualenv_check.sh Error: Command 'virtualenv' not found! Install python-virtualenv package Command '/bin/bash /tmp/tmpkWznFx/service/virtualenv_check.sh' returned non-zero exit status 127 See log: /tmp/tmp8IAJYB
Он говорит нам о том, что на стадии проверки зависимостей Makesite прервал установку. Команда virtualenv не была найдена в системе.
Мы можем поставить python-virtualenv и повторить попытку, но споткнемся на nginx, uwsgi или других зависимостях. Поэтому поставим все сразу одной командой.
sudo apt-get install python-virtualenv nginx uwsgi uwsgi-plugin-python nginx supervisor
sudo /etc/init.d/nginx start
Установка и удаление проекта
Note
Данные действия выполняются на сервере
Теперь повторим деплой нашего проекта:
$ makesite install awsdemo
Эта команда создаст следующую структуру директорий:
/var/www/master/ awsdemo/ | |-deploy/ # Файлы конфигурации |-logs/ # Логи nginx, supervisor, uwsgi |-media/ # Папка для загружаемых файлов |-service/ # Скрипты для обслуживания проекта |-source/ # Исходный код проекта |-static/ # Статика проекта |-.virtualenv/ # Виртуальное окружение проекта |-makesite.ini # Параметры проекта |-.makesite # Список шаблонов проекта
Сайт уже запущен и работает. Makesite скачал исходники, развернул виртуальное окружение, создал файлы конфигурации nginx, supervisor, uwsgi и подключил их, выполнил синхронизацию базы данных, скопировал файлы статики, а также создал shell скрипты для обновления, удаления и перезапуска проекта.
Для пробы удалим развернутый проект:
Note
В bash, для большинства команд Makesite, работает автодополнение.
# Указываем короткое имя проекта (ветка.проект)
$ makesite uninstall master.awsdemo
# Или можно указать полный путь
$ makesite uninstall /var/www/awsdemo/master
Проект удален из системы, nginx и supervisor перезагружены. Теперь можно развернуть его снова вышеприведенной командой.
Обновление проекта
Note
Данные действия выполняются локально
Изменим что-нибудь в нашем проекте, например добавим views.py:
from django.http import HttpResponse
def home(request):
return HttpResponse("Hello from makesite!")
Подключим его в urls.py:
...
# Examples:
url(r'^$', 'views.home', name='home'),
...
Сохраним и отправим изменения на сервер. Теперь на сервере достаточно ввести команду makesite update master.awsdemo, чтобы наш сайт обновился. При этом новые зависимости, миграции, статические файлы Makesite обработает самостоятельно.
В рамках данной статьи я планировал показать как создать свой хук на обновление репозитория в gitolite, чтобы git push в удаленный репозиторий вызывал автоматическое обновление соответствующих сайтов (по факту makesite update), но статья и так получилась достаточно длинной, поэтому эта задача предлагается к выполнению в качестве домашнего задания.
Note
Подробная статья про работу с Makesite находится в моих ближайших планах