Приветствую! В этой статье я приведу подробную инструкцию по деплою (развертыванию) проекта Django. Django - это свободный фреймворк для веб-приложений на языке Python, использующий шаблон проектирования MVC. Весь процесс я буду описывать на примере сервера с установленной операционной системой Ubuntu 20.04. Вы же можете использовать любую другую ОС, например, Debian. Алгоритм будет схожим.
Для начала вам необходимо выполнить начальную настройку своего Ubuntu сервера. Об этом я писал в прошлой статье.
sudo apt update
sudo apt upgrade
sudo apt install -y vim mosh tmux htop git curl wget unzip zip gcc build-essential make
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:
Во втором открывшемся окне выбираем пункт ru-RU.UTF-8 и также жмем Enter:
mosh hostgeek@45.82.178.214
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
Не буду перечислять их, можете загуглить самостоятельно. Скажу лишь, что необходимость в этих пакетах была выявлена на практике.
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. Не знаю как вам, а для меня это очень удобно
Также установим ZSH дефолтным шеллом:
chsh -s $(which zsh)
Нас интересует последняя актуальная версия языка Python, поэтому устанавливать будем из исходников. Для этого перейдем на официальный сайт Python, далее перейдем по ссылке на последнюю актуальную версию скрипта:
Открывшеюся страницу прокручиваем в самый них до раздела Files и копируем ссылку на архив:
На момент написания статьи актуальная версия - 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 введем команду:
exit()
В домашней папке (/home/hostgeek) создадим папку под наши проекты:
mkdir myapps
Перейдем в эту папку:
cd myapps
Здесь создадим папку под конкретный проект. В моем случае это будет парсер сайтов:
mkdir parser
Перейдем в эту папку:
cd parser
В этой папке создадим виртуальное окружение (env - название окружения, можно задавать любым):
~/.python/bin/python3.8 -m venv env
Активируем виртуальное окружение:
. env/bin/activate
Еще раз проапгрейдим pip:
pip install -U pip
Для установки вводим команду:
pip install django
Выполним команду, которая позволяет создать текстовый документ в котором перечислены все установленные и необходимые для работы Python приложения программные пакеты:
pip freeze > requirements.txt
Можно просмотреть содержимое этого файла:
nano requirements.txt
Для закрытия файла жмем Ctrl + X.
На этом этапе можно вытаскивать какой-либо проект с Гитхаба и запускать его. Но я покажу на примере создания чистого проекта с нуля.
Создаем новый проект (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 - наше созданное приложение и сохраним файл:
Можем запустить сервер командой (IP-адрес вставляете свой):
./manage.py runserver 45.82.178.214:8000
Теперь можем перейти в браузере по адресу http://45.82.178.214:8000 и увидеть следующую страницу:
Страница отображается таким образом, потому что не выполнена миграция базы данных. Можно накатить миграции и на данном этапе мы получим готовый Django-сервер, но он годится только для разработки. Дело в том, что если мы отключимся от сервера, то и Django-сервер "умрет" и станет недоступным по IP-адресу. Для продакшна же нужно, чтобы это сервер работал постоянно. Для этих целей нам пригодится 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
Откроем конфиг 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:
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) и сохраним файл:
Для активизации этих изменений нужно перезапустить Gunicorn. Для этого вводим команду:
htop
Жмем F4 (Filter) и вводим слово gunicorn. Так мы из общей массы отсортируем только процессы Gunicorn. Жмем на клавиатуре стрелку вниз и "киляем" все процессы поочередным нажатием клавиш F9 - 1 (SIGHUP) - Enter. Как видно, после "убийства" процессов они тут же запускаются автоматически, значит все работает правильно
Выходим из htop нажатием клавиши F10.
В конечном итоге сайт (а именно главная страница Django) должен открываться в браузере по IP-адресу (http://45.82.178.214) даже после того, как вы отключитесь от сервера.
Эта статья получилась уже довольно-таки объемной, поэтому подключение базы данных, привязка доменного имени, создание SSL-сертификата, настройка редиректов с "http" на "https", с "www" на "без www" и прочих, установка и настройка Memcached, а также установка и настройка FTP-сервера будут рассмотрены в отдельных статьях.
Если у вас возникли какие-либо вопросы по этой статье, то задавайте их в комментариях. Мы обязательно ответим. Спасибо за внимание!