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

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

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

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

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

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

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

<code>sudo apt update
sudo apt upgrade

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

<code>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. Обновляем локали (копируем все команды вместе и вставляем в терминал):

<code>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:

<code>mosh hostgeek@45.82.178.214

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

<code>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 python-pil python3-lxml libxslt-dev python-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-..."

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

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

<code>nano ~/.zshrc

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

<code>alias cls="clear"

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

<code>source ~/.zshrc

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

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

<code>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... 

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

<code>pwd

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

<code>cd ~/

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

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

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

<code>tar xvf Python-3.8.*

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

<code>cd Python-3.8.3

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

<code>./configure --enable-optimizations --prefix=/home/hostgeek/.python

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

<code>make -j1

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

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

<code>sudo make altinstall

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

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

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

<code>cd ..

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

<code>sudo rm -rf Python-3.8.3.tgz Python-3.8.3

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

<code>~/.python/bin/python3.8

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

Запуск Python 3

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

<code>exit()

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

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

<code>mkdir myapps

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

<code>cd myapps

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

<code>mkdir parser

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

<code>cd parser

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

<code>~/.python/bin/python3.8 -m venv env

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

<code>. env/bin/activate

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

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

<code>pip install -U pip

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

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

<code>pip install django

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

<code>pip freeze > requirements.txt

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

<code>nano requirements.txt

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

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

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

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

<code>django-admin startproject siteparser

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

<code>cd siteparser

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

<code>./manage.py startapp avitoparser

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

<code>nano siteparser/settings.py

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

settings py django

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

<code>./manage.py runserver 45.82.178.214:8000

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

Страница Django

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

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

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

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

<code>pip install gunicorn

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

<code>pip freeze > ../requirements.txt

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

<code>nano /home/hostgeek/myapps/parser/siteparser/gunicorn_config.py

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

<code>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:

<code>mkdir /home/hostgeek/myapps/parser/bin

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

<code>nano bin/start_gunicorn.sh

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

<code>#!/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.

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

<code>chmod +x bin/start_gunicorn.sh

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

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

<code>sudo nano /etc/nginx/sites-enabled/default

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

<code>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:

<code>sudo service nginx restart

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

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

<code>. ./bin/start_gunicorn.sh

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

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

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

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

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

<code>sudo nano /etc/supervisor/conf.d/siteparser.conf

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

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

<code>[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:

<code>sudo service supervisor stop

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

<code>sudo service supervisor start

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

<code>nano ~/myapps/parser/siteparser/siteparser/settings.py

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

IP адреса Django

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

<code>htop

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

Процессы Gunicorn

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

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

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

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

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