Разработка Django-приложения на PostgreSQL+Nginx+Gunicorn в Ubuntu 20.04
Development, Python, Ubuntu | Комментировать запись
Django – это производительный веб-фреймворк для разработки приложений Python. Django включает в себя упрощенный сервер разработки для локального тестирования кода, который ни в коем случае не рекомендуется использовать для производства – в такой среде требуется более безопасный и мощный веб-сервер.
Данный мануал поможет установить и настроить компоненты, необходимые для обслуживания приложений Django на сервере Ubuntu 20.04: система БД PostgreSQL (вместо стандартной SQLite), сервер приложений Gunicorn и Nginx (как обратный прокси-сервер для Gunicorn).
Требования
Для выполнения мануала понадобится:
- Свежий предварительно настроенный сервер Ubuntu 20.04.
- Пользователь с доступом к команде sudo.
Все необходимые рекомендации можно найти в мануале по начальной настройке сервера.
Фреймворк Django будет установлен в виртуальную среду (virtual environment), что позволит изолировать проект от общесистемной среды и использовать индивидуальные версии программ.
После того как мы запустим нашу базу данных и приложение, мы установим и настроим сервер приложений Gunicorn. Он будет служить интерфейсом нашего приложения, переводя клиентские запросы с HTTP на вызовы Python, которые может обрабатывать приложение. Затем мы настроим Nginx как прокси для Gunicorn, чтобы воспользоваться его высокопроизводительными механизмами обработки соединений и простыми в реализации функциями безопасности.
1: Установка зависимостей
Для начала нам нужно установить из репозиториев системы недостающие пакеты: менеджер пакетов pip, базу данных и связующие библиотеки.
Прежде чем начать установку, обновите индекс пакетов системы. Версии устанавливаемых пакетов зависят от версии Python 3, которую вы используете.
Чтобы установить зависимости Python 3, введите:
sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl
Django 1.11 – последняя версия Django, которая будет поддерживать Python 2. Если вы начинаете новые проекты, настоятельно рекомендуется перейти на Python 3. Если вам все еще нужен Python 2, введите:
sudo apt update
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl
Эта команда устанавливает pip, инструменты разработки Python, систему управления базами данных PostgreSQL и веб-сервер Nginx.
2: Создание базы данных и пользователя PostgreSQL
Теперь нужно создать БД и пользователя для приложения Django.
Для локальных соединений PostgreSQL по умолчанию использует схему так называемой одноранговой аутентификации (peer authentication). В целом это значит, что если имя пользователя операционной системы совпадает с именем валидного пользователя Postgres, данный системный пользователь может войти в СУБД без дополнительной аутентификации.
При установке PostgreSQL был создан пользователь операционной системы по имени postgres, что совпадает с пользователем postgres – администратором системы PostgreSQL. Он необходим для выполнения административных задач.
Измените пользователя и войдите как postgres. Для этого можно использовать sudo и опцию –u:
sudo -u postgres psql
Вы получите командную строку PostgreSQL.
Сначала нужно создать БД для проекта Django.
CREATE DATABASE myproject;
Примечание: Каждая команда должна заканчиваться точкой с запятой.
Затем создайте пользователя для новой БД и пароль для него:
CREATE USER myprojectuser WITH PASSWORD 'password';
После этого нужно изменить параметры подключения для нового пользователя. Это позволит ускорить выполнение операций базы данных, при этом значения не придётся запрашивать при установке каждого соединения.
Установите UTF-8 как кодировку по умолчанию, чего требует Django. Также установите схему по умолчанию изоляции транзакций «read committed», которая блокирует считывание с незавершенных транзакций. В завершение нужно установить часовой пояс. По умолчанию проекты Django будут использовать UTC.
ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser SET timezone TO 'UTC';
Передайте новому пользователю права на доступ к этой базе данных:
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
Закройте командную строку PostgreSQL:
\q
3: Создание виртуальной среды Python
Теперь нужно подготовить виртуальную среду Python, в которой будет храниться приложение и его зависимости. Для этого установите инструмент virtualenv, предварительно обновив pip:
# Python 3:
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv
# Python 2:
sudo -H pip install --upgrade pip
sudo -H pip install virtualenv
Создайте каталог для хранения приложения и перейдите в него:
mkdir ~/myprojectdir
cd ~/myprojectdir
Примечание: Вместо условного названия каталога укажите название вашего проекта.
В этом каталоге нужно создать виртуальную среду Python:
virtualenv myprojectenv
Эта команда создаст каталог myprojectenv в каталоге проекта myprojectdir и установит в нем локальную копию Python и pip. В этом каталоге можно настроить изолированную среду Python для проекта.
Прежде чем установить зависимости Python, нужно включить виртуальную среду.
source myprojectenv/bin/activate
Командная строка изменится. Это значит, что теперь вы работаете в виртуальной среде:
(myprojectenv)user@host:~/myprojectdir$
Теперь с помощью локального экземпляра pip можно установить Django, Gunicorn и psycopg2 (адаптер PostgreSQL).
pip install django gunicorn psycopg2-binary
Примечание: Вне зависимости от версии Python в виртуальной среде нужно использовать команду pip (не pip3).
4: Создание и настройка проекта Django
Теперь все компоненты Python установлены, можно приступать к разработке нашего проекта.
Создание проекта Django
Установите файлы проекта Django в подготовленный каталог. Это создаст каталог с кодом и поместит в него скрипт управления. Здесь мы определяем каталог явно, а не позволяем Django принимать решения относительно текущего каталога.
django-admin.py startproject myproject ~/myprojectdir
Теперь структура каталогов в ~/myprojectdir выглядит так:
- ~/myprojectdir/manage.py: скрипт управления проектом Django.
- ~/myprojectdir/myproject/: пакет проекта Django, который состоит из файлов __init__.py, settings.py, urls.py и wsgi.py.
- ~/myprojectdir/myprojectenv/: каталог виртуальной среды.
Настройка проекта
После этого нужно настроить проект. Откройте файл settings.py в текстовом редакторе:
nano ~/myprojectdir/myproject/settings.py
Найдите в файле директиву ALLOWED_HOSTS. Она содержит белый список адресов и доменов, которые могут подключаться к Django. Если входящий запрос содержит заголовок Host, который не включен в этот список, такой запрос будет сброшен. Это обеспечит дополнительный уровень безопасности Django.
Перечислите в квадратных скобках все заведомо безопасные для Django IP-адреса или домены. Каждый элемент нужно взять в одинарные кавычки. Все элементы списка разделяются запятыми. Чтобы добавить в список поддомены, поставьте перед доменным именем точку. В приведённом ниже фрагменте вы найдёте несколько закомментированных примеров того, как может выглядеть директива ALLOWED_HOSTS.
Примечание: Обязательно укажите localhost как один из параметров, поскольку позже мы будем проксировать соединения через локальный экземпляр Nginx.
. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']
Затем найдите DATABASES – раздел настроек доступа к БД. Здесь содержатся настройки для БД SQLite, однако проект использует БД PostgreSQL. Замените данные стандартной БД данными PostgreSQL.
Настройте Django для использования psycopg2. Укажите имя БД, имя и пароль пользователя базы данных, а затем укажите, что база данных находится на локальном компьютере. Настройки порта (параметр PORT) можно не заполнять.
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
Перейдите в конец файла и укажите, где должны находиться статические файлы. Это необходимо для того, чтобы веб-сервер Nginx мог обрабатывать запросы по этим файлам. Следующая строка поместит эти файлы в каталог под названием static в каталоге проекта:
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Сохраните и закройте файл.
Завершение настройки проекта
Теперь нужно переместить исходную схему базы данных в базу данных PostgreSQL:
~/myprojectdir/manage.py makemigrations
~/myprojectdir/manage.py migrate
Создайте администратора проекта:
~/myprojectdir/manage.py createsuperuser
Укажите имя, адрес электронной почты и пароль этого пользователя.
Переместите весь статический контент в отдельный каталог:
~/myprojectdir/manage.py collectstatic
Подтвердите операцию. Теперь все статические файлы хранятся в каталоге static.
Если вы включили базовый брандмауэр UFW, на данный момент порт сервера разработки Django (8000) заблокирован. Чтобы протестировать работу приложения, нам нужно разблокировать этот порт.
Для этого введите:
sudo ufw allow 8000
Теперь можно протестировать проект, запустив сервер разработки Django:
~/myprojectdir/manage.py runserver 0.0.0.0:8000
Откройте в браузере доменное имя или IP-адрес и укажите порт :8000.
http://server_domain_or_IP:8000
На экране появится приветственная страница Django:
It worked!
Congratulations on your first Django-powered page.
Добавьте /admin в конец адреса. Браузер запросит учётные данные администратора. Заполните появившиеся на экране поля, указав имя и пароль только что созданной учётной записи администратора при помощи команды createsuperuser. После этого на экране появится интерфейс администратора.
Завершив проверку, остановите сервер разработки, нажав CTRL+C в терминале.
Получив доступ к интерфейсу, вы убедились, что БД хранит информацию проекта и взаимодействует с ним.
Тестирование Gunicorn
Теперь нужно убедиться, что веб-сервер Gunicorn может обслуживать наше приложение. Перейдите в каталог проекта и попробуйте с помощью gunicorn загрузить модуль WSGI:
cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Эта команда запустит Gunicorn в том же интерфейсе, в котором до этого работал сервер разработки Django. Вернитесь и снова протестируйте приложение.
Примечание: Поскольку Gunicorn не знает о расположении статического контента для интерфейса администратора, интерфейс будет отображаться без CSS.
Чтобы передать серверу Gunicorn модуль, нужно указать путь к каталогу файла wsgi.py, который является точкой входа в приложение. Внутри этого файла находится функция application, которая используется для связи с приложением.
Читайте также: Настройка uWSGI и Nginx для обслуживания приложений Python
Завершив тестирование, нажмите в окне терминала CTRL-C, чтобы остановить сервер Gunicorn.
Теперь приложение Django готово. Отключите виртуальную среду:
deactivate
5: Создание сокета и сервиса systemd для Gunicorn
Мы убедились, что Gunicorn может взаимодействовать с нашим приложением Django, но теперь нам нужно настроить более надежный способ запуска и остановки сервера приложений. Для этого мы создадим файл сервиса systemd и сокетов.
Сокет Gunicorn будет создан при загрузке. Он будет прослушивать соединения. Когда происходит соединение, systemd автоматически запускает процесс Gunicorn для его обработки.
Для начала откройте файл сокета systemd для Gunicorn с привилегиями sudo:
sudo nano /etc/systemd/system/gunicorn.socket
Создайте раздел [Unit] (чтобы описать сокет), раздел [Socket] (в нем можно определить расположение сокета) и [Install] (позволяет убедиться, что сокет создается вовремя):
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Сохраните и закройте файл.
Теперь создайте и откройте сервис-файл для Gunicorn. Имя сервис-файла должно совпадать с именем сокета, не считая расширение.
sudo nano /etc/systemd/system/gunicorn.service
Добавьте раздел [Unit], который определяет метаданные и зависимости приложения. Внесите в него описание сервиса. Поскольку сервис работает в связке с сокетом, нужно включить директиву Requires, чтобы указать на эти отношения:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
Затем добавьте раздел [Service]. В нем нужно указать пользователя и группу, с помощью которых будет запущен сервис. Передайте текущему пользователю права на процесс и соответствующие файлы. Также права должна иметь группа www-data, тогда веб-сервер Nginx сможет взаимодействовать с процессом Gunicorn.
Затем нужно указать полный путь к исполняемому файлу Gunicorn, чтобы система инициализации знала, где искать эти файлы (в виртуальной среде). Systemd требует полного пути к исполняемым файлам Gunicorn в виртуальной среде. Привяжите процесс созданного сокета к каталогу /run. Выведите все данные на стандартный вывод, чтобы процесс journald мог вести логи Gunicorn. Также здесь можно указать любые дополнительные настройки Gunicorn. Например, в этом случае мы настроили три рабочих процесса (измените это в случае необходимости).
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=8host
Group=www-data
WorkingDirectory=/home/8host/myprojectdir
ExecStart=/home/8host/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
В конец файла нужно добавить раздел [Install], который определяет, к чему должен подключиться сервис во время запуска. Этот сервис должен запускаться, когда обычная многопользовательская система уже запущена и работает:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=8host
Group=www-data
WorkingDirectory=/home/8host/myprojectdir
ExecStart=/home/8host/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Итак, сервис systemd готов. Сохраните и закройте файл.
Запустите сокет Gunicorn. Это создаст сокет-файл в /run/gunicorn.sock (сейчас и при запуске системы). При создании подключения к этому сокету systemd автоматически запустит сервис gunicorn.service для его обработки.
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
6: Тестирование сокета Gunicorn
Теперь нужно проверить, как работает сокет. Запросите состояние процесса, чтобы убедиться, что он может запускаться.
sudo systemctl status gunicorn.socket
Вы получите такой вывод:
gunicorn.socket - gunicorn socket
Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor prese>
Active: active (listening) since Fri 2020-06-26 17:53:10 UTC; 14s ago
Triggers: ● gunicorn.service
Listen: /run/gunicorn.sock (Stream)
Tasks: 0 (limit: 1137)
Memory: 0B
CGroup: /system.slice/gunicorn.socket
Затем проверьте наличие файла gunicorn.sock в каталоге /run.
file /run/gunicorn.sock
/run/gunicorn.sock: socket
Если команда systemctl status отвечает, что произошла ошибка, или вы не нашли файл gunicorn.sock в каталоге, это указывает на то, что сокет Gunicorn не получилось создать правильно. Проверьте логи сокета Gunicorn:
sudo journalctl -u gunicorn.socket
Проверьте файл /etc/systemd/system/gunicorn.socket и устраните все проблемы, прежде чем продолжить.
7: Тестовая активация сокета
В настоящее время (если вы только запустили юнит gunicorn.socket) gunicorn.service не будет активен, так как с сокетом еще не было никаких соединений. Вы можете проверить это с помощью команды status:
sudo systemctl status gunicorn
gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Чтобы протестировать механизм активации сокета, создайте соединение:
curl --unix-socket /run/gunicorn.sock localhost
Вы должны увидеть HTML-вывод приложения в терминале. Это значит, что Gunicorn был запущен и может обслуживать приложение Django. Вы можете проверить, работает ли сервис Gunicorn:
sudo systemctl status gunicorn
gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2020-06-26 18:52:21 UTC; 2s ago
TriggeredBy: ● gunicorn.socket
Main PID: 22914 (gunicorn)
Tasks: 4 (limit: 1137)
Memory: 89.1M
CGroup: /system.slice/gunicorn.service
├─22914 /home/8host/myprojectdir/myprojectenv/bin/python /home/8host/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
├─22927 /home/8host/myprojectdir/myprojectenv/bin/python /home/8host/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
├─22928 /home/8host/myprojectdir/myprojectenv/bin/python /home/8host/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
└─22929 /home/8host/myprojectdir/myprojectenv/bin/python /home/8host/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
Jun 26 18:52:21 django-tutorial systemd[1]: Started gunicorn daemon.
Jun 26 18:52:21 django-tutorial gunicorn[22914]: [2020-06-26 18:52:21 +0000] [22914] [INFO] Starting gunicorn 20.0.4
Jun 26 18:52:21 django-tutorial gunicorn[22914]: [2020-06-26 18:52:21 +0000] [22914] [INFO] Listening at: unix:/run/gunicorn.sock (22914)
Jun 26 18:52:21 django-tutorial gunicorn[22914]: [2020-06-26 18:52:21 +0000] [22914] [INFO] Using worker: sync
Jun 26 18:52:21 django-tutorial gunicorn[22927]: [2020-06-26 18:52:21 +0000] [22927] [INFO] Booting worker with pid: 22927
Jun 26 18:52:21 django-tutorial gunicorn[22928]: [2020-06-26 18:52:21 +0000] [22928] [INFO] Booting worker with pid: 22928
Если вывод команды 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
Прежде чем продолжить, убедитесь, что ошибка устранена.
8: Настройка обратного прокси-сервера Nginx
Теперь приложение Gunicorn готово. Настройте Nginx для передачи трафика приложения.
Создайте новый блок server (виртуальный хост) в каталоге sites-available:
sudo nano /etc/nginx/sites-available/myproject
Добавьте в файл блок server. Задайте порт, который должен прослушивать веб-сервер (в данном случае – стандартный порт 80) и укажите доменное имя или IP в директиве server_name.
server {
listen 80;
server_name server_domain_or_IP;
}
Веб-сервер Nginx должен игнорировать проблемы с фавиконом. Затем нужно указать местонахождение статических файлов, собранных в каталоге ~/myprojectdir/static. У всех этих файлов стандартный префикс URI (/static), потому можно создать блок location для обслуживания этих запросов.
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/8host/myprojectdir;
}
}
Теперь создайте блок location / {} для всех остальных запросов. Добавьте в него стандартный файл proxy_params, который входит в установку Nginx, и направьте трафик на сокет Gunicorn.
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/8host/myprojectdir;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
Сохраните и закройте файл.
Чтобы включить файл, создайте симлинк на каталог sites-enabled.
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Проверьте синтаксис Nginx на наличие ошибок:
sudo nginx -t
Если ошибок нет, перезапустите Nginx:
sudo systemctl restart nginx
Теперь вы можете просмотреть приложение в браузере, открыв IP-адрес или домен и указав порт 80.
Поскольку порт сервера разработки (8000) больше не используется, его нужно заблокировать.
sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
Теперь откройте в браузере доменное имя или IP, чтобы просмотреть приложение.
Примечание: После настройки обратного прокси-сервера Nginx настоятельно рекомендуется защитить подключения при помощи сертификатов SSL/TLS. В противном случае все данные будут передаваться в виде простого текста и легко могут быть перехвачены злоумышленниками. Если у вас есть домен, вы можете получить бесплатный доверенный сертификат от Let’s Encrypt.
Читайте также: Создание сертификата Let’s Encrypt для Nginx в Ubuntu 20.04
9: Устранение неполадок Nginx и Gunicorn
Если в итоге ваше приложение не отображается, вам необходимо устранить неполадки в настройке.
Nginx открывает стандартную страницу вместо приложения Django
Если Nginx отображает страницу по умолчанию и не проксирует запросы для вашего приложения, попробуйте настроить директиву server_name в файле /etc/nginx/sites-available/myproject и указать в ней IP-адрес или доменное имя сервера.
Nginx использует директиву server_name, чтобы определить, какой блок server использовать для ответа на запросы. Если вы видите страницу Nginx по умолчанию, это значит, что Nginx не смог явно выполнить запрос к блоку sever, поэтому он вернулся к блоку по умолчанию, определенному в /etc/nginx/sites-available/default.
Директиву server_name в виртуальном хосте вашего проекта должна содержать более конкретное значение, чем виртуальный хост по умолчанию.
Nginx выдает ошибку 502 Bad Gateway
Ошибка 502 указывает, что Nginx не может успешно проксировать запрос. Ошибка 502 отображает широкий спектр проблем с конфигурацией, поэтому для устранения неполадок требуется дополнительная информация.
Основное место для поиска такой информации – это логи ошибок Nginx. Как правило, здесь можно узнать, какие условия вызвали проблемы во время проксирования. Чтобы открыть логи, введите:
sudo tail -F /var/log/nginx/error.log
Теперь сделайте в своем браузере еще один запрос, чтобы создать новую ошибку (попробуйте обновить страницу). Вы должны увидеть новое сообщение об ошибке, записанное в лог. Это сообщение поможет вам сузить проблему.
Вы можете увидеть следующее сообщение:
connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)
Это значит, что Nginx не смог найти файл gunicorn.sock в указанном месте. Вы должны сравнить расположение proxy_pass, определенное в файле /etc/nginx/sites-available/myproject, и фактическое расположение файла gunicorn.sock, созданного блоком gunicorn.socket systemd.
Если вы не можете найти файл gunicorn.sock в каталоге /run, вероятно, сокет-файл не смог его создать. Вернитесь к разделу 6 данного мануала.
Если вы получили:
connect() to unix:/run/gunicorn.sock failed (13: Permission denied)
Это указывает на то, что Nginx не смог подключиться к сокету Gunicorn из-за проблем с правами доступа. Это может произойти, когда процедура выполняется через пользователя root, а не sudo. Хотя systemd может создать файл сокета Gunicorn, Nginx не может получить к нему доступ.
Это бывает, если в какой-то точке между корневым каталогом (/) и файлом gunicorn.sock есть ограничения доступа. Чтобы просмотреть права сокет-файла и каждого из его родительских каталогов, передайте абсолютный путь к файлу сокета команде namei:
namei -l /run/gunicorn.sock
f: /run/gunicorn.sock
drwxr-xr-x root root /
drwxr-xr-x root root run
srw-rw-rw- root root gunicorn.sock
В выводе отображаются права для каждого из компонентов каталога. Изучив права доступа (первый столбец) и собственности (второй и третий столбец), вы можете выяснить, какой тип доступа открыт к сокету.
В приведенном выше примере файл сокета и каждый из каталогов, ведущих к нему, предоставляют право на чтение и выполнение всем пользователям (столбец прав для каталогов заканчивается на r-x вместо —). Значит, процесс Nginx может доступ к сокету.
Если какой-либо из каталогов, ведущих к сокету, не предоставляет таких прав, Nginx не сможет получить доступ к сокету. Также Nginx должен входить в группу, которая является владельцем сокет-файла.
Django выдает сообщение «could not connect to server: Connection refused»
При попытке получить доступ к приложению в веб-браузере Django может выдать такое сообщение:
OperationalError at /admin/login/
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
Это значит, что Django не может подключиться к базе данных Postgres. Убедитесь, что экземпляр Postgres запущен:
sudo systemctl status postgresql
Если БД не запущена, вы можете запустить ее и добавить ее в автозагрузку:
sudo systemctl start postgresql
sudo systemctl enable postgresql
Если это не решило проблему, убедитесь, что параметры базы данных, определенные в файле ~/myprojectdir/myproject/settings.py, указаны корректно.
Общие советы по устранению неполадок
При появлении любых неполадок всегда проверяйте логи – они могут сузить область ваших поисков. Проверьте каждый лог по очереди и найдите сообщения, указывающие на проблемные области.
- Лог процессов 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
При обновлении конфигурации или приложения вам, вероятно, потребуется перезапустить процессы, чтобы изменения вступили в силу.
Если вы обновите приложение Django, вы можете перезапустить процесс Gunicorn с помощью команды:
sudo systemctl restart gunicorn
Изменив сокет или сервис-файл Gunicorn, перезапустите демон и процесс:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
Отредактировав виртуальный хост Nginx, не забудьте проверить ошибки в файле и перезапустить веб-сервер:
sudo nginx -t && sudo systemctl restart nginx
Заключение
Теперь на сервере есть Django-проект в собственной виртуальной среде. Gunicorn может преобразовывать запросы в понятный Django формат. Веб-сервер Nginx настроен в качестве обратного прокси-сервера для обработки клиентских подключений.
Полученное тестовое приложение можно использовать в качестве шаблона или основы для разработки более сложного приложения.
Tags: Django, Gunicorn, NGINX, PostgreSQL, Python, Python 3, Ubuntu, Ubuntu 20.04, uWSGI+Nginx