В данном посте рассмотрим один из современных вариантов деплоя готового проекта Django в готовый режим работы. В посте будет рассмотрены моменты настройки и интеграции с Django таких инструментов, как:
- Nginx — WEB-сервер;
- Gunicorn — HTTP-сервер Python WSGI;
- Supervisor — менеджер процессов.
Исходные данные
Для использования данного поста требуются следующие исходные данные по ПО:
- готовый удаленный сервер Linux в виде VPS/VDS с выделенным IP;
- установленный и настроенный Python 3 c виртуальными средами и разрабатываемым проектом на Django;
Исходные данные по неймингу:
- /home/myprojectenv/ — абсолютный путь к папке виртуальной среды;
- /home/myprojectenv/myproject/ — абсолютный путь к папке проекта на Django;
- (myprojectenv)user@host: /myprojectenv/ — вид строки запроса в консоли под активной виртуальной средой Python;
- 11.22.33.44 — IP нашего удаленного сервера VDS/VPS;
- 8000 — порт, на котором будет подвешен наш проект.
Установка и настройка Nginx и Gunicorn
Для начала нужно сделать апгрейд
sudo apt-get update sudo apt-get upgrade
Ставим Nginx
sudo apt-get install nginx
Теперь заходим под виртуальную среду нашего(или вашего) проекта
cd /home/myprojectenv/ source bin/activate
Под активной виртуальной средой ставим Gunicorn
(myprojectenv)user@host: /home/myprojectenv# pip[pip3] install gunicorn
Замечание. Помните про версии pip. Если Python 2.x, то пишем pip, если Python 3.x — pip3. Это по дефолту, если у вас не настроено иначе.
Теперь, перед тем, как идти дальше, протестируем удачную установку Gunicorn и интеграцию с проектом Django и для этого выполняем команду
(myprojectenv)user@host: /home/myprojectenv/myproject# gunicorn myproject.wsgi:application --bind 11.22.33.44:8000
Идем в браузер и запускаем по адресу страницу 11.22.33.44:8000 и убеждаемся, что все ок.
Далее настраиваем папку статических файлов и для этого открываем файл настроек проекта в папке /home/myprojectenv/myproject/myproject/settings.py
nano settings.py
Добавляем в этот файл параметр STATIC_ROOT, если его нет, со следующим значением
... STATIC_ROOT = '/home/myprojectenv/myproject/static/' ...
Сохраняем, выходим и далее выполняем из папки проекта команду
(myprojectenv)user@host: /home/myprojectenv/myproject# python manage.py collectstatic
После чего в папке проекта появится новая папка с именем static.
Теперь идем и настраиваем Nginx по пути в файле
cd /etc/nginx/sites-available/
открываем файлик default
nano default
и перепишем некоторые моменты, как ниже
server { listen 80; server_name 11.22.33.44; #либо ip, либо доменное имя access_log /var/log/nginx/example.log; location /static/ { root /home/myprojectenv/myproject/; expires 30d; } location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $server_name; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
сохраняем и выходим.
Выполняем перезапуск Nginx, чтобы изменения вступили в силу
sudo service nginx restart
Активируем нашу среду и заходим в папку проекта для проверки запуска в связке Gunicon + Nginx
(myprojectenv)user@host: /home/myprojectenv/myproject# gunicorn myproject.wsgi:application
В браузере набираем 11.22.33.44:8000 и убеждаемся, что все ок.
Установка и настройка Supervisor
Чтобы ваше приложение стартовало после любого непредвиденного рестарта системы или сбоя, нам нужно использовать в деле supervisor.
Установим supervisor
apt-get install supervisor
Создадим конфигурационный файл для gunicorn в подпапке проекта (myproject/myproject/) рядом с settings.py
cd /home/myprojectenv/myproject/myproject touch gunicorn.conf.py nano gunicorn.conf.py
и записываем туда такие данные, которые означают, что данный проект будет запущен на IP и порте 0.0.0.0:8000, что будет означать внешний адрес нашего VPS. Если у вас сервер локальный, то ставим 127.0.0.1
bind = '0:8000' workers = 3 user = "nobody"
Теперь создаем конфигурационный файл для supervisor
cd /etc/supervisor/conf.d/ touch myproject.conf nano myproject.conf
и записываем туда такие данные
[program:myproject] command=/home/myprojectenv/bin/gunicorn myproject.wsgi:application -c /home/myprojectenv/myproject/myproject/gunicorn.conf.py directory=/home/myprojectenv/myproject user=nobody autorestart=true redirect_stderr=true
Запускаем проект через supervisor
supervisorctl restart myproject
В браузере набираем 11.22.33.44:8000 и убеждаемся, что все ок.
Дополнительный тест. Можно также перезагрузить сервер
shutdown -r nowи убедиться, что наш проекта на Django сам автоматом встал и заработал при помощи supervisor.
При использовании Supervisor необходимо использовать его подпроцесс управления supervisorctl. Остальные основные команды supervisor
- supervisorctl start myproject — запуск процесса;
- supervisorctl reread — перезапуск системы;
- supervisorctl update — обновить систему;
- supervisorctl status myproject — узнать статус процесса;
- supervisorctl remove myproject — удалить процесс.
Возможные ошибки использования Supervisor и Gunicorn
Ошибки в файлах конфигурации
Это с большей вероятностью, потому что конфигурационных файлов 2 и нужно, чтобы они были настроены слажено без ошибок. Напомним, что они у нас находятся по путям:
- Файл конфигурации Gunicorn в пределах текущего проекта /home/myprojectenv/myproject/myproject/gunicorn.conf.py
- Файл конфигурации проекта в виде управляемого процесса внутри Supervisor /etc/supervisor/conf.d/myproject.conf
Ошибка запуска из-за занятости стандартного порта Supervisor
Обычно, эта ошибка выглядит так, при запуске команды запуска supervisorctl start myproject
cloudApp: ERROR (spawn error)
или так, при запуске команды поиска ошибок supervisord -n
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord
Для решения этой проблемы сначала убиваем процесс Supervisor, который можно сделать несколькими способами.
Первый. Выводим весь список процессов Supervisor и убиваем нужный по PID(в списке он будет после первого)
ps -ef | grep supervisord sudo kill -9 PID_OUR_PROJECT
или
ps -ef | grep supervisord kill -s SIGTERM PID_OUR_PROJECT
Второй. Убиваем сам supervisord
sudo pkill supervisord
Третий. Удаляем файл supervisor.sock и запускаем supervisor обратно
sudo unlink /run/supervisor.sock sudo /etc/init.d/supervisor start
Теперь перезапускаем проект
supervisorctl start cloudApp
Ошибка ERROR (no such process) при запуске нового процесса
Данная ошибка появляется, когда мы создали новый проект, но он не обновился в системе Supervisot и для решения этой проблемы нам нужно перезаписать все процессы и перезагрузить supervisorctl
supervisorctl reread supervisorctl reload
Если не удается идентифицировать ошибку
Если проблему трудно найти или идентифицировать, то будет полезной использовать команду
supervisord -n
который выведет весь список ошибок в файлах или сервисах, которые мешают запускаться процессу Supervisor.
Использованные материалы:
- Django + Python3 + Nginx + Gunicorn + DO;
- Setting up Django with Nginx, Gunicorn, virtualenv, supervisor and PostgreSQL