Настройка Django+PosgtreSQL+Gunicorn
Настроили виртуальное окружение
Установили и настроили Postgresql
Далее внутри виртуального окружения ставим необходимый пакет программ
Ставим Django и Gunicorn внутри виртуального окружения.
Gunicorn будет выступать в качестве HTTP сервера для сайта.
(dj-project) $ pip3 install django gunicorn
Смотрим какие при этом зависимости установились
(dj-project) $ pip3 freeze Django==2.2.4
Создаём Django-проект
(dj-project) $ django-admin.py startproject myproject
Сохраняем зависимости
(dj-project) $ pip freeze > myproject/requirements.txt
Настройка проекта
После этого нужно настроить проект. Откройте файл settings.py в текстовом редакторе:
$ mcedit /var/www/myprojectdir/myproject/settings.py
Находим в файле директиву ALLOWED_HOSTS. Она содержит белый список адресов и доменов, которые могут подключаться к Django. Если входящий запрос содержит заголовок Host, который не включен в этот список, такой запрос будет сброшен. Это обеспечит дополнительный уровень безопасности Django. Перечислите в квадратных скобках все заведомо безопасные для Django IP-адреса или домены. Каждый элемент нужно взять в одинарные кавычки. Все элементы списка разделяются запятыми. Чтобы добавить в список поддомены, поставьте перед доменным именем точку. В приведённом ниже фрагменте вы найдёте несколько закомментированных примеров того, как может выглядеть директива ALLOWED_HOSTS. При DEBUG равном True и при выполнении тестов проверка отключена. Проверка обычно нужна только на боевом сервере.
Примечание: Обязательно укажите localhost как один из параметров, поскольку позже мы будем проксировать соединения через локальный экземпляр Nginx.
Затем находим раздел настроек доступа к БД — DATABASES. Указваем имя БД, имя и пароль пользователя базы данных, а затем укажите, что база данных находится на локальном компьютере.
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'django_db', 'USER' : 'user_name', 'PASSWORD' : 'password', 'HOST' : '127.0.0.1', 'PORT' : '5432',
Переходим в конец файла и указываем, где должны находиться статические файлы. Это необходимо для того, чтобы веб-сервер Nginx мог обрабатывать запросы по этим файлам. Следующая строка поместит эти файлы в каталог под названием static в каталоге проекта:
STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
В окружении проекта устанавливаем бэкэнд для PostgreSQL
(dj-project) $ pip install psycopg2
При ошибке Error: pg_config executable not found.
Указываем путь до pg_config
PATH=$PATH:/usr/lib/postgresql/12/bin/
и устанавливаем пакет для разработки клиентских приложений и серверных расширений.
Выполнение миграций базы данных
Django обладает одним очень большим преимуществом — он имеет встроенную админку, что очень облегчает жизнь. Но чтобы она заработала, необходимо выполнить миграцию базы данных, то есть подготовить из моделей данных SQL запросы, которые сформируют структуру базу данных.
cd ./myproject
(dj-project)python manage.py makemigrations
(dj-project)python manage.py migrate
А ещё создадим суперпользователя, который будет администратором с максимальными правами доступа к вашему сайту. Выполните следующую команду и следуйте инструкциям.
(dj-project)python manage.py createsuperuser
Переместите весь статический контент в подготовленный каталог:
(dj-project)python manage.py collectstatic
Подтвердите операцию. Теперь все статические файлы хранятся в каталоге static.
Теперь можно протестировать проект, запустив сервер разработки Django
(dj-project)python manage.py runserver 0.0.0.0:8000
Открываем в браузере доменное имя или IP-адрес и указываем порт :8000.
http://server_domain_or_IP:8000
На экране появится приветственная страница Django.
Добавьте /admin в конец адреса. Браузер запросит учётные данные администратора. Заполните поля, указав имя и пароль только что созданной учётной записи администратора при помощи команды createsuperuser. После этого на экране появится интерфейс администратора.
Завершив проверку, останавливаем сервер разработки, нажав CTRL-C в окне терминала.
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Эта команда запустит Gunicorn в том же интерфейсе, в котором до этого работал сервер разработки Django. Вернемся и снова протестируем приложение.
Примечание: Поскольку Gunicorn не знает о расположении статического контента для интерфейса администратора, интерфейс будет отображаться без использования стилей.
Завершим проверку, останавливаем Gunicorn, нажав CTRL-C в окне терминала.
Создание системных сокетов и служебных файлов для Gunicorn
Мы проверили, что Gunicorn может взаимодействовать с нашим приложением Django, но мы должны реализовать более надежный способ запуска и остановки сервера приложений. Для этого мы создадим файлы службы systemd и сокетов.
Сокет Gunicorn будет создан при загрузке и будет прослушивать соединения. Когда происходит соединение, systemd автоматически запускает процесс Gunicorn для обработки соединения.
Создадим файла сокета systemd для Gunicorn:
sudo mcedit /etc/systemd/system/gunicorn.socket
Внутри мы создадим
[Unit] раздел для описания сокета,
[Socket] раздел для определения местоположения сокета и
[Install] раздел, чтобы убедиться, что сокет создан в нужное время:
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target
Далее создаем служебный файл systemd для Gunicorn. Имя файла службы должно соответствовать имени файла сокета, за исключением расширения:
sudo mcedit /etc/systemd/system/gunicorn.service
Начните с [Unit]раздела, который используется для указания метаданных и зависимостей. Мы поместим здесь описание нашего сервиса и сообщим системе инициализации запускать его только после того, как цель сети достигнута. Поскольку наш сервис опирается на сокет из файла сокета, нам нужно включить Requires директиву, чтобы указать эту связь:
[Unit] раздел, который используется для указания метаданных и зависимостей. Мы поместим здесь описание нашего сервиса и сообщить системе инициализации запускать его только после того, как цель сети достигнута. Поскольку наш сервис запускается через сокет, нам нужно включить Requires директиву, чтобы указать эту связь:
[Service] раздел. Здесь мы определим пользователя и группу, под которой мы хотим работать. Предоставим доступ группе www-data, чтобы Nginx мог легко общаться с Gunicorn.
Затем укажем рабочий каталог и команду для запуска сервиса. В этом случае нам нужно будет указать полный путь к исполняемому файлу Gunicorn, который устанавливается в нашей виртуальной среде. Свяжем процесс с сокетом Unix, который мы создали в /run каталоге, чтобы процесс мог взаимодействовать с Nginx. Записываем все данные в стандартный вывод, чтобы journald процесс мог собирать журналы Gunicorn. Также можем указать любые дополнительные настройки Gunicorn здесь. Например, мы указали 3 рабочих процесса:
[Install] раздел. Он указывает systemd, с чем связать этот сервис, если мы включим его при загрузке. Мы хотим, чтобы эта служба запускалась и работала, когда обычная многопользовательская система:
[Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/myprojectdir/myproject/ ExecStart=/var/www/myprojectdir/venv/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ myproject.wsgi:application [Install] WantedBy=multi-user.target
Теперь запустим и включим сокет Gunicorn. Следующие команды создадут файл сокета /run/gunicorn.sock сейчас и при следующей загрузке системы Когда будет установлено соединение с этим сокетом, systemd автоматически начнет обрабатывать его gunicorn.service :
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
Для того чтобы проверить , что операция прошла успешно, проверив наличие файла сокета.
Проверка на наличие файла сокета Gunicorn
Проверьте состояние процесса:
sudo systemctl status gunicorn.socket
Далее, проверьте наличие gunicorn.sock файла в /runкаталоге:
file /run/gunicorn.sock
Output /run/gunicorn.sock: socket
Если в результате работы команды systemctl status произошла ошибка, или если вы не нашли gunicorn.sock файл в каталоге, это означает, что сокет Gunicorn не был создан правильно. Проверьте логи сокета Gunicorn, набрав:
sudo journalctl -u gunicorn.socket
Еще раз посмотрите настройки в файле /etc/systemd/system/gunicorn.socket и исправить проблемы, прежде чем продолжить.
Для проверки работы и активации сокета, подключимся curl через сокет :
curl --unix-socket /run/gunicorn.sock localhost
В консоли должно быть отображено содержание HTML страницы. Это указывает на то, что Gunicorn был запущен и смог обработать ваше приложение Django.
Проверяем что служба Gunicorn работает:
sudo systemctl status gunicorn
Если возникли проблемы после curl или systemctl status, проверяем в журналах дополнительную информацию:
sudo journalctl -u gunicorn
Проверяем и при необходимости вносим изменения /etc/systemd/system/gunicorn.service. После внесения изменении файл /etc/systemd/system/gunicorn.service, необходимо перезагрузите демон, чтобы перечитать конфиг сервиса и перезапустить процесс Gunicorn:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
Настроить Nginx на Proxy Pass для Gunicorn
Теперь, когда Gunicorn настроен, нам нужно настроить Nginx.
Создаем нового виртуальный сервер Nginx :
sudo mcedit /etc/nginx/sites-available/myproject
В блоке server. Указываем что будем прослушивать порт 80 и он должен отвечать на доменное имя или IP-адрес нашего сервера:
server { listen 80; server_name server_domain_or_IP; location /static/ { root /var/www/myprojectdir/myproject; } location = /favicon.ico { alias /var/www/myprojectdir/myproject/static/favicon.ico; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { alias /var/www/myprojectdir/myproject/static/robots.txt; } location /media/ { root /var/www/myprojectdir/myproject/media; } # Взаимодействуем с Django-приложением через unix-сокет location / { include proxy_params; include /etc/nginx/uwsgi_params; proxy_pass http://unix:/run/gunicorn.sock; } }
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Проверим конфигурацию Nginx на наличие синтаксических ошибок:
sudo nginx -t
Если ошибок нет, перезапускаем Nginx:
sudo systemctl restart nginx