Я занималась штампованием django-сайтиков и потому возникла необходимость максимальной автоматизации различных процессов, связанных с разработкой, деплоем и поддержкой проектов, вследствие чего мной было разработано несколько решений. Одним из них я поделюсь в этой статье – это скрипт деплоя проекта на пустую debian-машину, с ним развётрывание стало лёгким и непринуждённым. Под катом Вы найдёте инструкцию, как развернуть django-приложение за 10 минут, из них 5 займёт чтение статьи и ещё 5 – собственно дело. Способ годен для начинающих, не имеющих никаких знаний в админстве.
Для того, чтобы выложить проект, нужно его подготовить, купить сервер, развернуть и всё протестировать.
1. Подготовка проекта:
Если проекта как такового у Вас нет, то можете пропустить этот шаг. Мой скрипт по умолчанию будет загружать пустой django-проект с моего гитхаба.
Если проект уже есть:
- Нужно загрузить проект в git-репозиторий либо подправить скрипт на код, который будет вытаскивать проект из нужного места (wget, например).
- В корне проекта должен лежать файл requirements со всеми pip-зависимостями. Отмечу, что там обязательно должны стоять версии пакетов.
- В корне должен быть корректный файл wsgi.py (по умолчанию в последних версиях django он лежит в projectname/, так вот, его оттуда нужно перенести в ../)
- Опционально там же может находиться файл с apt-зависимостями под именем apt-requirements.
- Корректный файл settings. В качестве базы по умолчанию будем использовать MySQL, поэтому в поле ENGINE должно стоять значение ‘django.db.backends.mysql’.
Примеры этих файлов, которые кочуют у меня из проекта в проект, можно посмотреть в тестовом django-проекте.
2. Подготовка хостинга:
Вы можете выбрать любой хостинг с debian дистрибутивом, главное – иметь права рута. Я буду рассказывать по шагам, как настраивать VDS на FirstVDS. Для начала можно выбрать специальный тестовый тариф VDS-Разминка за 60 руб в месяц либо VDS-Старт за 200 руб. У меня на одном сервере (тариф Разгон, 350 руб) было размещено около 20 среднестатистических клиентских сайта, всё работало исправно.
- Итак, переходим на FirstVDS.
- Регистрируемся, входим в личный кабинет.
- На главной: Заказать услугу -> Виртуальный сервер -> VDS-OVZ-Разминка (или Старт)-> Заказать.
- Доменное имя пишем любое, Шаблон ОС – Debian (! это важно), панель управления – это гуй, он стоит 150 руб в месяц, мы вполне обойдёмся и без него. Снимаем галочку.
- Привязываем номер телефона, оплачиваем сервер и ждём активации (примерно 5 мин). После этого должно прийти уведомление с доступами на email.
- Подключаемся к серверу по ssh через рута.
3. Развёртывание:
Так как мы зашли под рутом, то нужно создать нового обычного пользователя и работать через него. Я написала мини-скрипт, делающий это:
#! /bin/bash
if [ $# -eq 0 ]
then
echo "Введите имя нового пользователя, который будет рулить сайтом. (Не рут же это будет, в самом деле)"
else
useradd -m $1 # добавляем юзера
passwd $1 # назначаем ему пароль
echo "$1 ALL=(ALL) ALL" >> /etc/sudoers # делаем судоером
chsh -s /bin/bash $1
cd /home/$1/
# скачиваем код скрипта c gist
wget https://gist.github.com/kpx13/51e37fbd2b457cd6d821/raw/70ad75f0164c97abdcd30660ae359f6c468fe213/django_deploy_script.sh
chown $1:$1 django_deploy_script.sh
chmod ug+x django_deploy_script.sh # делаем его исполняемым
fi
Скрипт хранится на gist, поэтому мы выкачиваем его и выполняем команды:
wget https://gist.github.com/kpx13/51e37fbd2b457cd6d821/raw/e5c8393c64a3c9123e31228095bfae1f282b2d17/initial_script.sh
/bin/bash initial_script.sh <юзернейм нового пользователя>
su <юзернейм>
cd
После этого видим в домашней директории файл django_deploy_script.sh с содержимым:
#! /bin/bash
#аргументы ниже нужно заполнить!
PROJECT_NAME="django_empty_project" # * название проекта
GITHUB_PROJECT="https://github.com/kpx13/django_empty_project.git" # * адрес гитхаб-репозитория
DB_ROOT_PASSWORD="asdf" # * пароль рута от MySQL
DB_NAME="mysql_db_name" # * конфиг БД (должен совпадать с конфигом в settings.py) название БД
DB_USER="mysql_db_user" # * юзер
DB_PASSWORD="mysql_db_password" # * пароль
APACHE_SERVER_NAME="yoursite.ru" # домен
GITHUB_EMAIL="[email protected]" # конфиг для гитхаба, эмейл
GITHUB_USERNAME='annkpx' # конфиг для гитхаба, юзернэйм
# конец аргументов
APACHE_LISTEN="$(hostname --ip-address):80"
THIS_PATH=$PWD
PROJECT_ROOT=$THIS_PATH/$PROJECT_NAME
# установка базовых пакетов
distr_install ()
{
echo "Устанавливаем ПО..."
sudo apt-get update
yes | sudo apt-get install apache2 libapache2-mod-wsgi # необходимо для работы связки apache + django
yes | sudo apt-get install python-dev python-pip # необходимо для работы связки python + mysql
yes | sudo apt-get install libjpeg62 libjpeg62-dev libfreetype6 libfreetype6-dev zlib1g-dev # необходимо для графики и шрифтов
# MySQL + Python
read -p "Сейчас будет устанавливаться MySQL, в синем окне Вы должны 2 раза ввести пароль рута для базы: $DB_ROOT_PASSWORD"
yes | sudo apt-get install mysql-server
yes | sudo apt-get install python-mysqldb
}
# выкачивание репозитория с кодом
git_init ()
{
# если будет использоваться не git, а что-то другое, эту функцию нужно переписать
yes | sudo apt-get install git
echo "Клонируем репозиторий с гитхаба..."
echo "192.30.252.128 github.com" | sudo tee --append /etc/hosts # всвязи с суицидниками на гитхабе
git clone $GITHUB_PROJECT
echo ".*
*.pyc
env/
logs/
static/" > $PROJECT_ROOT/.gitignore # стандартный файл .gitignore, можно отредактировать
git config --global user.email $GITHUB_EMAIL
git config --global user.name $GITHUB_USERNAME
}
# удовлетворение зависимостей
project_req ()
{
echo "Устанавливаем зависимости..."
cat $PROJECT_ROOT/apt-requirements | xargs sudo apt-get install # установка apt-зависимостей
sudo pip install -r $PROJECT_ROOT/requirements # установка pip-зависимостей
}
# создание базы MySQL
create_db ()
{
# если будет использоваться другая база, заменить эту часть
mysql -u root -p$DB_ROOT_PASSWORD -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD'"
mysql -u root -p$DB_ROOT_PASSWORD -e "CREATE DATABASE $DB_NAME"
mysql -u root -p$DB_ROOT_PASSWORD -e "GRANT ALL ON $DB_NAME.* TO $DB_USER@localhost"
echo "БД установлена..."
}
# инициализация в джанго
django ()
{
cd $PROJECT_ROOT
echo "Собираем статику..."
mkdir media 2>/dev/null
mkdir media/uploads 2>/dev/null
python manage.py collectstatic
echo "Синхронизируем БД..."
python manage.py syncdb
}
# установка apache
apache_set()
{
# настройка связки с apache
cd $PROJECT_ROOT
echo "Alias /media/ $PROJECT_ROOT/media/
<Directory $PROJECT_ROOT/media>
Order allow,deny
Options -Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
Alias /static/ $PROJECT_ROOT/static/
<Directory $PROJECT_ROOT/static>
Order allow,deny
Options -Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
WSGIScriptAlias / $PROJECT_ROOT/wsgi.py
" > httpd.conf
echo "<VirtualHost $APACHE_LISTEN >
ServerName $APACHE_SERVER_NAME
CustomLog $PROJECT_ROOT/logs/access.log combined
DocumentRoot $PROJECT_ROOT
ErrorLog $PROJECT_ROOT/logs/error.log
ServerAlias www.$APACHE_SERVER_NAME
Include '$PROJECT_ROOT/httpd.conf'
</VirtualHost>
WSGIPythonPath $PROJECT_ROOT
" | sudo tee /etc/apache2/sites-enabled/$PROJECT_NAME
chmod -R ugo+rw media/
chmod -R a+rw media/
mkdir logs 2>/dev/null
sudo /etc/init.d/apache2 restart
}
# деплой под ключ на пустой машине
all ()
{
echo "Выполняем деплой проекта под ключ."
distr_install
git_init
project_req
create_db
django
apache_set
echo "Скрипт отработан."
exit
}
clear
clear
echo "
Скрипт выполняется последовательно, по шагам. Можно запустить выполнение сразу всех шагов используя пункт меню 7 или пройти по всем меню подряд для пущего контроля.
Меню:"
OPTIONS="ПО Гит Зависимости БазаДанных Джанго apache ВСЁ Выход"
select opt in $OPTIONS
do
case $opt in
"ПО") distr_install ;;
"Гит") git_init ;;
"Зависимости") project_req ;;
"БазаДанных") create_db ;;
"Джанго") django ;;
"apache") apache_set ;;
"ВСЁ") all ;;
"Выход") exit ;;
esac
done
Если необходимо, редактируем его: проставляем нужные аргументы в начале. Но можно для теста оставить всё как есть. И исполняем файл:
./django_deploy_script.sh
Можно выбрать пункт меню 7, тогда всё будет установлено «под ключ», либо пройти последовательно от 1 до 6.
Когда скрипт отработает, заходим на сервер по ip и оцениваем результат.
Заключение.
Когда я только начинала делать сайтики на django, деплой проектов у меня занимал время, соизмеримое со временем разработки. С опытом всё изменилось. За эти годы я разработала конвейер, который позволяет и быстро создавать сайты, и быстро деплоить. Есть аналогичный скрипт для деплоя на nginx, если нужно – выложу. Я делала так: у меня был свой сервер на nginx, там было много сайтов со своими виртуальными окружениями. Перед тем, как разместить у клиента на отдельном сервере, я размещала и отлаживала сайт у себя, а после оплаты переносила на отдельный хостинг.