image

Автор: dcontm 25 февраля 2020

Теги: Django Production Gunicorn Nginx PostgreSQL

Разворачиваем Django проект с Postgres, Nginx и Gunicorn на Ubuntu 18.04

 

Предисловие

 

В сегодняшнем руководстве мы рассмотрим, как развернуть ваш проект в production. Эта статья является вольным пересказом великолепного руководства на DigitalOcean. Предполагается, что у вас есть сервер Ubuntu 18.04, предварительно настроенный. Как настроить сервер, вы можете посмотреть здесь. Иcпользуемая версия Python - 3.6.9. В качестве базы данных будем использовать PostgreSQL, настроим Gunicorn для общения с нашим Django приложением, также будем использовать сервер Nginx. Nginx будет будет обслуживать все входящие запросы к нашему приложению, передавая их Gunicorn.

  1. Установка необходимых пакетов.
  2. Создание и настройка базы данных.
  3. Настройка виртуальной среды.
  4. Создание и настройка нового проекта Django.
  5. Настройка и демонизация сервера Gunicorn.
  6. Настройка Nginx.
  7. Устранение неисправностей.

 

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

 

Для начала обновим локальный индекс пакетов apt, воспользовавшись следующей командой:

$ sudo apt-get update

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

$ sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

После выполнения команды на ваш удаленный компьютер будут установлены библиотеки разработки Python3, система базы данных PostgreSQL, библиотека взаимодействия с ней, а также веб-сервер Nginx.

 

Создание и настройка базы данных

 

Следующим шагом будет создание базы данных для нашего проекта и нового пользователя, которому будут принадлежать база данных. По умолчанию при установке PostgreSQL автоматически был создан пользователь с именем postgres. Сейчас мы сможем использовать его для выполнения некоторых административных задач. Для этого войдем в интерактивную сессию Postgres:

$ sudo -u postgres psql

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

postgres=# CREATE DATABASE my_database;

Далее создаем базу данных пользователя для нашего проекта. Убедитесь, что вы выбрали надежный пароль (пароль в одинарных кавычках):

postgres=# CREATE USER my_user WITH PASSWORD 'my_password';

После этого мы изменим некоторые параметры подключения для пользователя, которого мы только что создали. Мы установим кодировку по умолчанию UTF-8, которую ожидает Django. Мы также установим схему изоляции транзакции по умолчанию «read commit», которая блокирует чтение из незафиксированных транзакций. Наконец, мы устанавливаем часовой пояс. По умолчанию наши проекты Django будут настроены на использование UTC. Это все рекомендации самого проекта Django:

postgres=# ALTER ROLE my_user SET client_encoding TO 'utf8';
postgres=# ALTER ROLE my_user SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE my_user SET timezone TO 'UTC';

Последним шагом будет наделение нашего пользователя возможностью управлять созданной базой данных:

postgres=# GRANT ALL PRIVILEGES ON DATABASE my_database TO my_user;

Теперь можно выйти из интерактивного режима:

postgres=# \q

Postgres настроен так, что Django может подключаться и управлять информацией своей базы данных.

 

Настройка виртуальной среды

 

Виртуальную среду создадим с помощью команды virtualenv, которую установим при помощи pip. Предварительно обновим pip:

$ sudo -H pip3 install --upgrade pip
$ sudo -H pip3 install virtualenv

После установки virtualenv мы можем приступить к созданию каталогов для нашего проекта:

$ mkdir ~/my_project
$ cd ~/my_project

Теперь после того как мы перешли в созданный нами каталог, создадим нашу виртуальную среду:

$ virtualenv venv

Внутри будет установлена локальная версия Python и pip, это защитит нас от конфликтов версий различных пакетов. Осталось активировать нашу виртуальную среду:

$ source venv/bin/activate

После активации виртуальной среды мы можем установить Django, Gunicorn и psycopg2 (драйвер для работы с PostgreSQL):

(venv) $ pip install django gunicorn psycopg2-binary

Выполнив все перечисленные действия, мы имеем все необходимое для запуска нашего Django проекта.

 

Создание и настройка нового проекта Django

 

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

(venv) $ django-admin.py startproject django_project

После выполнения этой команды вы получите следующую иерархию каталогов и файлов:

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

(venv) $ nano django_project/django_project/settings.py

Найдите и измените следующие переменные:

~/my_project/django_project/django_project/settings.py

#Укажите ваш домен и хост, не хабудьте включить в список localhost

ALLOWED_HOSTS = ['ваш домен или IP', 'localhost']
..........................................................................................

# Измените настройки используемой базы данных
DATABASES = {
   
'default': {
       
'ENGINE': 'django.db.backends.postgresql_psycopg2',
       
'NAME': 'my_database',
       
'USER': 'my_user',
       
'PASSWORD': 'my_password',
       
'HOST': 'localhost',
       
'PORT': '',
   

}
..........................................................................................
# Укажите местоподлжение ваших статических файлов
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

 

После внесения всех изменений сохраните и закройте файл. Вы можете получить больше информации по настройкам Django в открытой среде тут.

Нам осталось выполнить несколько заключительных настроек перехода к следующему этапу. Создадим и добавим исходные схемы базы данных Django в нашу базу PostgreSQL:

(venv) $ django_project/manage.py makemigrations
(venv) $ django_project/manage.py migrate

Cоздадим суперпользователя с правами администратора:

(venv) $ django_project/manage.py createsuperuser

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

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

(venv) $ django_project/manage.py collectstatic

Для того, чтобы проверить работоспособность нашего Django приложения, запустим его. Если вы выполнили настройку операционной системы в соответствии с предыдущей статьей, у вас должен быть настроен брандмауер UFW, отбрасывающий все подлючения, кроме как OpenSSH (порт), поэтому первым действием будет открытие дополнительного порта:

(venv) $ sudo ufw allow 8000

Наконец мы можем запустить сервер разработки:

(venv) $ django_project/manage.py runserver

Откройте браузер и перейдите по адресу http//:<ваш домен или IP>:8000, вы должны увидеть экран приветсвия Django.

Чтобы остановить сервер разработки, находясь в консоле, нажмите CTRL+C. После успешного завершения предыдущих шагов вы можете выйти из виртуального окружения.

(venv) $ deactivate

 

Настройка и демонизация сервера Gunicorn

 

Прежде чем заняться демонизацией Gunicorn, давайте убедимся в его работоспособности на переднем плане:

(venv) $ django-project/gunicorn --bind 0.0.0.0:8000 django_project.wsgi

Здесь мы запустили Gunicorn, указав относительный путь точки входа в наше приложение. Теперь, если сервер успешно запустился, вы можете перейти в браузер и протестировать ваше приложение по адресу http//:<ваш домен или IP>:8000. Обратите внимание, что оформление вашего приложения будет без css стилей, так как мы не указали Gunicorn, где найти статику. Позднее работу со статическими данными возьмет на себя Nginx.

Самое время заняться автоматизацией запуска, перезапуска и остановки сервера Gunicorn. Для этого мы создадим файл службы systemd и сокет. Gunicorn сокет будет создан при загрузке и будет прослушивать входящие соединения.

Для начала создадим для Gunicorn сокет службы systemd:

$ sudo nano /etc/systemd/system/gunicorn.socket

Добавим и сохраним в открывшемся файле следующее:

/etc/systemd/system/gunicorn.socket

[Unit]

Description=gunicorn socket

[Socket]

ListenStream=/run/gunicorn.sock

[Install]

WantedBy=sockets.target

 

Затем создайте и служебный файл systemd для Gunicorn. Имя файла должно соответствовать имени сокета, за исключением его разрешения.

$ sudo nano /etc/systemd/system/gunicorn.service

Поместите в него следующее содержимое:

/etc/systemd/system/gunicorn.service

[Unit]

Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target


[Service]

User=my_user
Group=www-data
WorkingDirectory=/home/my_user/my_project/django_project
ExecStart=/home/my_user/my_project/venv/bin/gunicorn \
          --access-logfile - \
         
--workers 3 \
         
--bind unix:/run/gunicorn.sock \
         
myproject.wsgi:application

[Install]

WantedBy=multi-user.target

 

На этом наш сервисный файл systemd завершен - можете закрыть и сохранить его. Теперь нам нужно запустить и включить сокет Gunicorn. Это создаст файл сокета /run/gunicorn.sock сейчас и при загрузке. Когда будет установлено соединение с этим сокетом, gunicorn.service будет обрабатывать его:

$ sudo systemctl start gunicorn.socket
$ sudo systemctl enable gunicorn.socket 

Чтобы проверить, что все запустилось и работает успешно, выполним проверку работы процесса:

$ sudo systemctl status gunicorn.socket

Проверим наличие файла сокета:

$ file /run/gunicorn.sock

В случае если при запуске возникают какие-то ошибки, вы можете посмотреть журнал логирования с помощью утилиты journalctl:

$ sudo journalctl -u gunicorn.socket

В большинстве случаев неполадки возникают в следствии неправильно указанных путей до исполняемых файлов.

В настоящее время, хоть мы и успешно запустили сокет, gunicorn.service ещё не активен, поскольку он не получал никаких подключений. Мы можем убедиться в этом:

$ sudo systemctl status gunicorn

Вывод будет следующим:

gunicorn.service - gunicorn daemon

    Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)

    Active: inactive (dead)

Чтобы проверить механизм активации сокета, мы можем отправить соединение через сокет curl, набрав:

$ curl --unix-socket /run/gunicorn.sock localhost

Вы должны увидеть вывод HTML кода вашего приложения. Чтобы убедиться, что Gunicorn работает, введите:

$ sudo systemctl status gunicorn

В выводе вы должны увидеть, что Gunicorn активен:

● gunicorn.service - gunicorn daemon
   Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
   Active: active (running) since Sat 2020-02-08 23:47:53 UTC; 6s ago  
Main PID: 27851 (gunicorn)
    Tasks: 4 (limit: 1124)
   CGroup: /system.slice/gunicorn.service
           ├─27851 /home/my_user/my_project/venv/bin/python3 /home/dcontm/tiny/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock django_project.wsgi:application
           ├─27854 /home/my_user/my_project/venv/bin/python3 /home/dcontm/tiny/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock django_project.wsgi:application
           ├─27855 /home/my_user/my_project/venv/bin/python3 /home/dcontm/tiny/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock django_project.wsgi:application
           └─27858 /home/my_user/my_project/venv/bin/python3 /home/dcontm/tiny/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock django_project.wsgi:application

 

Если выходные данные curl или systemctl status указывают на то, что возникла проблема, проверьте журналы для получения дополнительной информации:

$ sudo journalctl -u gunicorn

Обратите внимание, если вы внесете изменения в /etc/systemd/system/gunicorn.service файл, перезагрузите демон, чтобы перезапустить процесс Gunicorn в новой конфигурации, набрав:

$ sudo systemctl daemon-reload
$ sudo systemctl restart gunicorn

Убедитесь, что все работает, прежде чем продолжить.

 

Настройка Nginx

 

После того как вы убедились, что все работает, пришло время сконфигурировать Nginx на передачу всех запросов Gunicorn серверу. Для этого создадим файл конфигурации нашего проекта:

$ sudo nano /etc/nginx/sites-available/my_project

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

/etc/nginx/sites-available/myproject

server {

    listen 80;
    server_name домен и/или IPсервера;

    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
      root /home/my_user/my_project/django_project;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

 

В настройках мы указали, что Nginx должен прослушивать 80 порт и отвечать на доменное имя и/или IP нашего сервера. Также мы указали расположение наших статических файлов и favicon изображения (при этом игнорируем все ошибки, связанные с ним). В последнем блоке мы настроили прокси, теперь все запросы Nginx передает нашему Gunicorn сокету. После того как вы закончили, сохраните и закройте файл. Теперь мы можем применить наш файл конфигурации, связав его с sites-enabled каталогом. Для этого создадим символьную ссылку:

$ sudo ln -s /etc/nginx/sites-available/my_project /etc/nginx/sites-enabled

Проверьте ваш файл конфигурации на синтаксические ошибки:

$ sudo nginx -t

Если все хорошо, перезапустите Nginx:

$ sudo systemctl restart nginx

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

$ sudo ufw delete allow 8000
$ sudo ufw allow 'Nginx Full'

Теперь вы можете открыть браузер и просмотреть ваше приложение, использовав для этого доменное имя или IP-адрес.

 

Устранение неисправностей

 

При различных возникающих ошибках вы можете почерпнуть информацию из различных журналов логирования:

  • Проверьте журналы процесса Nginx, набрав: sudo journalctl -u nginx
  • Проверьте журналы доступа Nginx, набрав: sudo less /var/log/nginx/access.log
  • Проверьте журналы ошибок Nginx, набрав: sudo less /var/log/nginx/error.log
  • Проверьте журналы приложений Gunicorn, набрав: sudo journalctl -u gunicorn
  • Проверьте журналы сокетов Gunicorn, набрав: sudo journalctl -u gunicorn.socket

Не забывайте после изменения конфигурации перезагружать демон службы или сервера:

$ sudo systemctl restart gunicorn
$ sudo systemctl restart nginx

$ sudo systemctl restart gunicorn.socket gunicorn.service
$ sudo systemctl daemon-reload

 

Резюме

 

В этом руководстве мы установили Django в виртуальной среде, настроили сервер Gunicorn для взаимодействия с Django. После этого мы настроили Nginx в качестве обратного прокси-сервера. Статья получилась довольно объемной, тем не менее вся изложенная информация является необходимой и достаточной для развертывания вашего Django приложения в production.

0  0  532 

Только авторизированные пользователи могут оставлять комментарии
Войти через VK

Коментарии 0