Деплой приложения Django (Nginx + Gunicorn + Supervisor)

Внимание! Это 2-я часть из серии статей по деплою (развертыванию) Django-приложения. Перед ее прочтением рекомендуем ознакомиться с другими частями:
1. Начальная настройка сервера
2. Деплой Django-приложения (текущая статья)
3. Подключение базы данных PostgreSQL
4. Установка и привязка Memcached к Django
5. Привязка домена к серверу Django, настройка SSL и редиректов

Деплой Django

Где я арендую высококачественные VDS/VPS для своих проектов по низким ценам? Конечно же здесь! wink

Приветствую! В этой статье я приведу подробную инструкцию по деплою (развертыванию) проекта Django. Django - это свободный фреймворк для веб-приложений на языке Python, использующий шаблон проектирования MVC. Весь процесс я буду описывать на примере сервера с установленной операционной системой Ubuntu 20.04. Вы же можете использовать любую другую ОС, например, Debian. Алгоритм будет схожим.

Для начала вам необходимо выполнить начальную настройку своего Ubuntu сервера. Об этом я писал в прошлой статье.

Инструкция по деплою приложения Django

1. Обновляем пакеты:

sudo apt update
sudo apt upgrade

2. Устанавливаем необходимый для работы софт:

sudo apt install -y vim mosh tmux htop git curl wget unzip zip gcc build-essential make
  • vim - мощный текстовый редактор (можно обойтись без него, так как Ubuntu имеет другие встроенные текстовые редакторы, например, nano);
  • mosh - аналог ssh, но только более быстрый (также можно обойтись без него, но с ним работать комфортнее);
  • tmux - терминальный оконный менеджер и мультиплексор, позволяющий использовать несколько терминалов в одном. Необязательный пакет;
  • htop - предназначен для вывода на терминал списка запущенных процессов и информации о них. Более функциональный аналог top;
  • git - распределённая система управления версиями;
  • curl - программа командной строки, позволяющая взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL;
  • wget - свободная неинтерактивная консольная программа для загрузки файлов по сети;
  • unzip и zip - утилиты для работы с zip-архивами;
  • gcc - набор компиляторов для различных языков программирования;
  • build-essential - это метапакет, в котором содержатся ссылки на необходимые пакеты;
  • make - утилита, автоматизирующая процесс преобразования файлов из одной формы в другую (компиляция).

3. Обновляем локали (копируем все команды вместе и вставляем в терминал):

sudo localedef ru_RU.UTF-8 -i ru_RU -fUTF-8 ; \
export LANGUAGE=ru_RU.UTF-8 ; \
export LANG=ru_RU.UTF-8 ; \
export LC_ALL=ru_RU.UTF-8 ; \
sudo locale-gen ru_RU.UTF-8 ; \
sudo dpkg-reconfigure locales

В первом открывшемся окне выбираем пункт ru_RU.UTF-8 UTF-8 и жмем Enter:

Настройка локали Ubuntu

Во втором открывшемся окне выбираем пункт ru-RU.UTF-8 и также жмем Enter:

Настройка локали Ubuntu-20.04

4. Теперь при желании можно переподключиться к серверу через Mosh:

mosh hostgeek@45.82.178.214

5. Устанавливаем необходимые пакеты и библиотеки:

sudo apt install -y zsh tree redis-server nginx libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-dev python3-pil python3-lxml libxslt-dev python3-libxml2 libffi-dev libssl-dev python-dev gnumeric libsqlite3-dev libpq-dev libxml2-dev libxslt1-dev libjpeg-dev libfreetype6-dev libcurl4-openssl-dev supervisor

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

6. Устанавливаем Oh-My-ZSH:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

Oh-My-ZSH - это это фреймворк с открытым исходным кодом, предназначенный для управления конфигурацией оболочки ZSH. Проще говоря, это более современная и привлекательная командная оболочка.

Также я обычно настраиваю алиас cls для очистки терминала. Для этого нужно открыть конфигурационный файл ZSH:

nano ~/.zshrc

В самом конце файла вставить строчку, сохранить файл:

alias cls="clear"

И перезагрузить этот файл:

source ~/.zshrc

Теперь терминал можно очищать по команде cls. Не знаю как вам, а для меня это очень удобно blush

Также установим ZSH дефолтным шеллом:

chsh -s $(which zsh)

7. Установка Python

Нас интересует последняя актуальная версия языка Python, поэтому устанавливать будем из исходников. Для этого перейдем на официальный сайт Python, далее перейдем по ссылке на последнюю актуальную версию скрипта:

Актуальная версия Python

Открывшеюся страницу прокручиваем в самый них до раздела Files и копируем ссылку на архив:

Скачать Python

На момент написания статьи актуальная версия - Python 3.8.3. Ссылка на архив имеет следующий вид:

https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz

Убедимся, что находимся в домашней директории (/home/hostgeek). Hostgeek - это папка с именем моего пользователя. У вас она будет иметь другое название. Проверить текущий путь можно командой:

pwd

Если находимся не в этой папке, то перейдем в нее:

cd ~/

Скачиваем архив Python в эту папку:

wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz

Распаковываем архив:

tar xvf Python-3.8.*

Переходим в распакованную папку:

cd Python-3.8.3

Конфигурируем:

./configure --enable-optimizations --prefix=/home/hostgeek/.python

Запускаем сборку (цифра 1 означает количество ядер на сервере, вы ставите свою цифру):

make -j1

Этот процесс довольно-таки долгий и длится около 15 минут.

Выполним установку двоичных файлов Python:

sudo make altinstall

Отлично, Python установлен. Теперь проапгрейдим pip (пакетный менеджер Python):

sudo /home/hostgeek/.python/bin/python3.8 -m pip install -U pip

Вернемся на папку выше (в папку /home/hostgeek):

cd ..

И удалим скачанный архив Python и распакованную папку:

sudo rm -rf Python-3.8.3.tgz Python-3.8.3

И наконец-то проверим корректность установки Python, запустив его командой:

~/.python/bin/python3.8

Как видим, все работает:

Запуск Python 3

Для выхода из Python введем команду:

exit()

8. Создадим директорию проекта

В домашней папке (/home/hostgeek) создадим папку под наши проекты:

mkdir myapps

Перейдем в эту папку:

cd myapps

Здесь создадим папку под конкретный проект. В моем случае это будет парсер сайтов:

mkdir parser

Перейдем в эту папку:

cd parser

В этой папке создадим виртуальное окружение (env - название окружения, можно задавать любым):

~/.python/bin/python3.8 -m venv env

Активируем виртуальное окружение:

. env/bin/activate
Если нужно будет выйти из виртуального окружения, то используйте команду деактивации - deactivate

Еще раз проапгрейдим pip:

pip install -U pip

9. Устанавливаем Django

Для установки вводим команду:

pip install django

Выполним команду, которая позволяет создать текстовый документ в котором перечислены все установленные и необходимые для работы Python приложения программные пакеты:

pip freeze > requirements.txt

Можно просмотреть содержимое этого файла:

nano requirements.txt

Для закрытия файла жмем Ctrl + X.

10. Запуск проекта

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

Создаем новый проект (siteparser - имя проекта, вы задаете свое):

django-admin startproject siteparser

Перейдем в папку созданного проекта:

cd siteparser

Создадим здесь первое приложение (avitoparser - имя приложения, вы задаете свое):

./manage.py startapp avitoparser

Откроем файл настроек Django - settings.py, который находится по адресу /home/hostgeek/myapps/parser/siteparser/siteparser. Мы сейчас находимся в папке /home/hostgeek/myapps/parser/siteparser, поэтому для открытия файла выполним команду:

nano siteparser/settings.py

В ALLOWED_HOSTS пропишем IP-адрес нашего сервера, а в INSTALLED_APPS - наше созданное приложение и сохраним файл:

settings py django

Можем запустить сервер командой (IP-адрес вставляете свой):

./manage.py runserver 45.82.178.214:8000

Теперь можем перейти в браузере по адресу http://45.82.178.214:8000 и увидеть следующую страницу:

Страница Django

Для остановки сервера воспользуйтесь комбинацией клавиш Ctrl + C

Страница отображается таким образом, потому что не выполнена миграция базы данных. Можно накатить миграции и на данном этапе мы получим готовый Django-сервер, но он годится только для разработки. Дело в том, что если мы отключимся от сервера, то и Django-сервер "умрет" и станет недоступным по IP-адресу. Для продакшна же нужно, чтобы это сервер работал постоянно. Для этих целей нам пригодится Gunicorn - автономный веб-сервер.

11. Установка Gunicorn

Для установки выполним команду:

pip install gunicorn

Зафризим его в том самом файле requirements.txt:

pip freeze > ../requirements.txt

Создадим конфигурационный файл Gunicorn в папке /home/hostgeek/myapps/parser/siteparser:

nano /home/hostgeek/myapps/parser/siteparser/gunicorn_config.py

Вставим и сохраним в нем следующий код:

command = '/home/hostgeek/myapps/parser/env/bin/gunicorn'
pythonpath = '/home/hostgeek/myapps/parser/siteparser'
bind = '127.0.0.1:8001'
workers = 3
user = 'hostgeek'
limit_request_fields = 32000
limit_request_field_size = 0
raw_env = 'DJANGO_SETTINGS_MODULE=siteparser.settings'

workers = 3 - это количество ядер сервера умноженное на 2 плюс 1 (1 ядро * 2 + 1 = 3). В последней строчке siteparser соответствует имени приложения Django, которое лежит в папке parser.

Перейдем в папку /home/hostgeek/myapps/parser/ и создадим в ней папку bin:

mkdir /home/hostgeek/myapps/parser/bin

В папке bin создадим файл start_gunicorn.sh (это bash-скрипт, который будет запускать Gunicorn):

nano bin/start_gunicorn.sh

Добавим и сохраним в этом файле следующее содержимое:

#!/bin/bash
source /home/hostgeek/myapps/parser/env/bin/activate
exec gunicorn -c /home/hostgeek/myapps/parser/siteparser/gunicorn_config.py siteparser.wsgi

siteparser.wsgi соответствует имени Django-приложения, которое лежит в папке parser.

Выдадим права на выполнение этого файла:

chmod +x bin/start_gunicorn.sh

12. Настройка Nginx

Откроем конфиг Nginx:

sudo nano /etc/nginx/sites-enabled/default

Удалим из него все закомментированные строчки, а также кусок кода:

location / {
    try_files $uri $uri/ =404;
}

Вместо него вставим следующий код:

location / {
    proxy_pass http://127.0.0.1:8001;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
    add_header Access-Control-Allow-Origin *;
}

Сохраним файл и перезапустим Nginx:

sudo service nginx restart

Теперь, если в браузере перейти по IP-адресу http://45.82.178.214 можно наблюдать надпись "502 Bad Gateway".

Запустим наш скрипт:

. ./bin/start_gunicorn.sh

Теперь при переходе по IP-адресу http://45.82.178.214 мы увидим главную страницу Django:

Главная страница Django

13. Настройка Supervisor

Supervisor - это система для управления сервисами. Нужна она для автоматического перезапуска Gunicorn, если он "упадет".

Создадим конфиг в папке:

sudo nano /etc/supervisor/conf.d/siteparser.conf

Имя конфига соответствует имени Djando-проекта, который лежит в папке parser.

Вставим и сохраним в нем следующий код:

[program:gunicorn]
command=/home/hostgeek/myapps/parser/bin/start_gunicorn.sh
user=hostgeek
process_name=%(program_name)s
numproc=1
autostart=1
autorestart=1
redirect_stderr=true

Остановим Supervisor:

sudo service supervisor stop

И запустим его:

sudo service supervisor start

Откроем конфигурационный файл Django:

nano ~/myapps/parser/siteparser/siteparser/settings.py

В ALLOWED_HOSTS добавим локальный IP (127.0.0.1) и сохраним файл:

IP адреса Django

Для активизации этих изменений нужно перезапустить Gunicorn. Для этого вводим команду:

htop

Жмем F4 (Filter) и вводим слово gunicorn. Так мы из общей массы отсортируем только процессы Gunicorn. Жмем на клавиатуре стрелку вниз и "киляем" все процессы поочередным нажатием клавиш F9 - 1 (SIGHUP) - Enter. Как видно, после "убийства" процессов они тут же запускаются автоматически, значит все работает правильно blush

Процессы Gunicorn

Выходим из htop нажатием клавиши F10.

В конечном итоге сайт (а именно главная страница Django) должен открываться в браузере по IP-адресу (http://45.82.178.214) даже после того, как вы отключитесь от сервера.

Эта статья получилась уже довольно-таки объемной, поэтому подключение базы данных, привязка доменного имени, создание SSL-сертификата, настройка редиректов с "http" на "https", с "www" на "без www" и прочих, установка и настройка Memcached, а также установка и настройка FTP-сервера будут рассмотрены в отдельных статьях.

Если у вас возникли какие-либо вопросы по этой статье, то задавайте их в комментариях. Мы обязательно ответим. Спасибо за внимание!

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