Django — это мощная веб-система, помогающая создать приложение или сайт Python с нуля. Django включает упрощенный сервер разработки для локального тестирования кода, однако для серьезных производственных задач требуется более защищенный и мощный веб-сервер.
В этом руководстве мы покажем, как установить и настроить определенные компоненты Ubuntu 18.04 для поддержки и обслуживания приложений Django. Вначале мы создадим базу данных PostgreSQL вместо того, чтобы использовать базу данных по умолчанию SQLite. Мы настроим сервер приложений Gunicorn для взаимодействия с нашими приложениями. Затем мы настроим Nginx для работы в качестве обратного прокси-сервера Gunicorn, что даст нам доступ к функциям безопасности и повышения производительности для обслуживания наших приложений.
Для прохождения этого обучающего модуля вам потребуется новый экземпляр сервера Ubuntu 18.04 с базовым брандмауэром и пользователем с привилегиями sudo
и без привилегий root. Чтобы узнать, как настроить такой сервер, воспользуйтесь нашим модулем Руководство по начальной настройке сервера.
Мы будем устанавливать Django в виртуальной среде. Установка Django в отдельную среду проекта позволит отдельно обрабатывать проекты и их требования.
Когда база данных будет работать, мы выполним установку и настройку сервера приложений Gunicorn. Он послужит интерфейсом нашего приложения и будет обеспечивать преобразование запросов клиентов по протоколу HTTP в вызовы Python, которые наше приложение сможет обрабатывать. Затем мы настроим Nginx в качестве обратного прокси-сервера для Gunicorn, чтобы воспользоваться высокоэффективными механизмами обработки соединений и удобными функциями безопасности.
Давайте приступим.
Чтобы начать данную процедуру нужно загрузить и установить все необходимые нам элементы из хранилищ Ubuntu. Для установки дополнительных компонентов мы немного позднее используем диспетчер пакетов Python pip
.
Нам нужно обновить локальный индекс пакетов apt
, а затем загрузить и установить пакеты. Конкретный состав устанавливаемых пакетов зависит от того, какая версия Python будет использоваться в вашем проекте.
Если вы используете Django с 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 для последующего построения сервера Gunicorn, СУБД Postgres и необходимые для взаимодействия с ней библиотеки, а также веб-сервер Nginx.
Вначале мы создадим базу данных и пользователя базы данных для нашего приложения Django.
По умолчанию Postgres использует для локальных соединений схему аутентификации «peer authentication». Это означает, что если имя пользователя операционной системы совпадает с действительным именем пользователя Postgres, этот пользователь может войти без дополнительной аутентификации.
Во время установки Postgres был создан пользователь операционной системы с именем postgres
, соответствующий пользователю postgres
базы данных PostgreSQL, имеющему права администратора. Этот пользователь нам потребуется для выполнения административных задач. Мы можем использовать sudo и передать это имя пользователя с опцией -u
.
Выполните вход в интерактивный сеанс Postgres, введя следующую команду:
- sudo -u postgres psql
Вы увидите диалог PostgreSQL, где можно будет задать наши требования.
Вначале создайте базу данных для своего проекта:
- CREATE DATABASE myproject;
Примечание. Каждое выражение Postgres должно заканчиваться точкой с запятой. Если с вашей командой возникнут проблемы, проверьте это.
Затем создайте пользователя базы данных для нашего проекта. Обязательно выберите безопасный пароль:
- CREATE USER myprojectuser WITH PASSWORD 'password';
Затем мы изменим несколько параметров подключения для только что созданного нами пользователя. Это ускорит работу базы данных, поскольку теперь при каждом подключении не нужно будет запрашивать и устанавливать корректные значения.
Мы зададим кодировку по умолчанию UTF-8
, чего и ожидает Django. Также мы зададим схему изоляции транзакций по умолчанию «read committed», которая будет блокировать чтение со стороны неподтвержденных транзакций. В заключение мы зададим часовой пояс. По умолчанию наши проекты Django настроены на использование времени по Гринвичу (UTC
). Все эти рекомендации взяты из проекта Django:
- 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
Теперь настройка Postgres завершена, и Django может подключаться к базе данных и управлять своей информацией в базе данных.
Мы создали базу данных, и теперь можем перейти к остальным требованиям нашего проекта. Для удобства управления мы установим наши требования Python в виртуальной среде.
Для этого нам потребуется доступ к команде virtualenv
. Для установки мы можем использовать pip
.
Если вы используете Python 3, обновите pip
и установите пакет с помощью следующей команды:
- sudo -H pip3 install --upgrade pip
- sudo -H pip3 install virtualenv
Если вы используете Python 2, обновите pip
и установите пакет с помощью следующей команды:
- sudo -H pip install --upgrade pip
- sudo -H pip install virtualenv
После установки virtualenv
мы можем начать формирование нашего проекта. Создайте каталог для файлов нашего проекта и перейдите в этот каталог:
- mkdir ~/myprojectdir
- cd ~/myprojectdir
Создайте в каталоге проекта виртуальную среду Python с помощью следующей команды:
- virtualenv myprojectenv
Эта команда создаст каталог myprojectenv
в каталоге myprojectdir
. В этот каталог будут установлены локальная версия Python и локальная версия pip
. Мы можем использовать эту команду для установки и настройки изолированной среды Python для нашего проекта.
Прежде чем установить требования Python для нашего проекта, необходимо активировать виртуальную среду. Для этого можно использовать следующую команду:
- source myprojectenv/bin/activate
Командная строка изменится, показывая, что теперь вы работаете в виртуальной среде Python. Она будет выглядеть примерно следующим образом: (myprojectenv)user@host:~/myprojectdir$
.
После запуска виртуальной среды установите Django, Gunicorn и адаптер psycopg2
PostgreSQL с помощью локального экземпляра pip
:
Примечание. Если виртуальная среда активна (когда перед командной строкой стоит (myprojectenv)
), необходимо использовать pip
вместо pip3
, даже если вы используете Python 3. Копия инструмента в виртуальной среде всегда имеет имя pip
вне зависимости от версии Python.
- pip install django gunicorn psycopg2-binary
Теперь у вас должно быть установлено все программное обеспечение, необходимое для запуска проекта 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/
: виртуальный каталог, которы мы создали до этого.Прежде всего, необходимо изменить настройки созданных файлов проекта. Откройте файл настроек в текстовом редакторе:
- nano ~/myprojectdir/myproject/settings.py
Найдите директиву ALLOWED_HOSTS
. Она определяет список адресов сервера или доменных имен, которые можно использовать для подключения к экземпляру Django. Любой входящий запрос с заголовком Host, не включенный в этот список, будет вызывать исключение. Django требует, чтобы вы использовали эту настройку, чтобы предотвратить использование определенного класса уязвимости безопасности.
В квадратных скобках перечислите IP-адреса или доменные имена, связанные с вашим сервером Django. Каждый элемент должен быть указан в кавычках, отдельные записи должны быть разделены запятой. Если вы хотите включить в запрос весь домен и любые субдомены, добавьте точку перед началом записи. В следующем фрагменте кода для демонстрации в строках комментариев приведено несколько примеров:
Примечание. Обязательно используйте 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,
который мы установили вместе с pip
. Нам нужно указать имя базы данных, имя пользователя базы данных, пароль пользователя базы данных, и указать, что база данных расположена на локальном компьютере. Вы можете оставить для параметра PORT
пустую строку:
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
Затем перейдите в конец файла и добавьте параметр, указывающий, где следует разместить статичные файлы. Это необходимо, чтобы Nginx мог обрабатывать запросы для этих элементов. Следующая строка указывает Django, что они помещаются в каталог 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. Чтобы протестировать сервер разработки, необходимо разрешить доступ к порту, который мы будем использовать.
Создайте исключение для порта 8000 с помощью следующей команды:
- sudo ufw allow 8000
Теперь вы можете протестировать ваш проект, запустив сервер разработки Django с помощью следующей команды:
- ~/myprojectdir/manage.py runserver 0.0.0.0:8000
Откройте в браузере доменное имя или IP-адрес вашего сервера с суффиксом :8000
:
http://server_domain_or_IP:8000
Вы увидите страницу индекса Django по умолчанию:
Если вы добавите /admin
в конце URL в панели адреса, вам будет предложено ввести имя пользователя и пароль администратора, созданные с помощью команды createsuperuser
:
После аутентификации вы получите доступ к интерфейсу администрирования Django по умолчанию:
Завершив изучение, нажмите CTRL+C в окне терминала, чтобы завершить работу сервера разработки.
Перед выходом из виртуальной среды нужно протестировать способность Gunicorn обслуживать приложение. Для этого нам нужно войти в каталог нашего проекта и использовать gunicorn
для загрузки модуля WSGI проекта:
- cd ~/myprojectdir
- gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Gunicorn будет запущен на том же интерфейсе, на котором работал сервер разработки Django. Теперь вы можете вернуться и снова протестировать приложение.
Примечание. В интерфейсе администратора не будут применяться в стили, поскольку Gunicorn неизвестно, как находить требуемый статичный контент CSS.
Мы передали модуль в Gunicorn, указав относительный путь к файлу Django wsgi.py
, который представляет собой точку входа в наше приложение. Для этого мы использовали синтаксис модуля Python. В этом файле определена функция application
, которая используется для взаимодействия с приложением. Дополнительную информацию о спецификации WSGI можно найти здесь.
После завершения тестирования нажмите CTRL+C в окне терминала, чтобы остановить работу Gunicorn.
Мы завершили настройку нашего приложения Django. Теперь мы можем выйти из виртуальной среды с помощью следующей команды:
- deactivate
Индикатор виртуальной среды будет убран из командной строки.
Мы убедились, что 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
Сохраните файл и закройте его после завершения.
Теперь создайте и откройте служебный файл systemd для Gunicorn в текстовом редакторе с привилегиями sudo
. Имя файла службы должно соответствовать имени файла сокета за исключением расширения:
- 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, установленному в нашей виртуальной среде. Мы привяжем процесс к сокету Unix, созданному в каталоге /run
, чтобы процесс мог взаимодействовать с Nginx. Мы будем регистрировать все данные на стандартном выводе, чтобы процесс journald
мог собирать журналы Gunicorn. Также здесь можно указать любые необязательные настройки Gunicorn. Например, в данном случае мы задали 3 рабочих процесса:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
Наконец, добавим раздел [Install]
. Это покажет systemd, куда привязывать эту службу, если мы активируем ее запуск при загрузке. Нам нужно, чтобы эта служба запускалась во время работы обычной многопользовательской системы:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/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
Успешность операции можно подтвердить, проверив файл сокета.
Проверьте состояние процесса, чтобы узнать, удалось ли его запустить:
- 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
и устраните любые обнаруженные проблемы, прежде чем продолжить.
Если вы запустили только gunicorn.socket
, служба gunicorn.service
не будет активна в связи с отсутствием подключений к совету. Для проверки можно ввести следующую команду:
- sudo systemctl status gunicorn
Output● 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 запущен и может обслуживать ваше приложение Django. Вы можете убедиться, что служба Gunicorn работает, с помощью следующей команды:
- sudo systemctl status gunicorn
Output● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2018-07-09 20:00:40 UTC; 4s ago
Main PID: 1157 (gunicorn)
Tasks: 4 (limit: 1153)
CGroup: /system.slice/gunicorn.service
├─1157 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─1178 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─1180 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
└─1181 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
Jul 09 20:00:40 django1 systemd[1]: Started gunicorn daemon.
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.sock (1157)
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
Jul 09 20:00:41 django1 gunicorn[1157]: - - [09/Jul/2018:20:00:41 +0000] "GET / HTTP/1.1" 200 16348 "-" "curl/7.58.0"
Если результат вывода 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
Обязательно устраните вышеперечисленные проблемы, прежде чем продолжить.
Мы настроили Gunicorn, и теперь нам нужно настроить Nginx для передачи трафика в процесс.
Для начала нужно создать и открыть новый серверный блок в каталоге Nginx sites-available
:
- sudo nano /etc/nginx/sites-available/myproject
Откройте внутри него новый серверный блок. Вначале мы укажем, что этот блок должен прослушивать обычный порт 80, и что он должен отвечать на доменное имя или IP-адрес нашего сервера:
server {
listen 80;
server_name server_domain_or_IP;
}
Затем мы укажем Nginx игнорировать любые проблемы при поиске favicon. Также мы укажем, где можно найти статичные ресурсы, собранные нами в каталоге ~/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/sammy/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/sammy/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
Нам нужна возможность открыть брандмауэр для обычного трафика через порт 80. Поскольку нам больше не потребуется доступ к серверу разработки, мы можем удалить правило и открыть порт 8000:
- sudo ufw delete allow 8000
- sudo ufw allow 'Nginx Full'
Теперь у вас должна быть возможность перейти к домену или IP-адресу вашего сервера для просмотра вашего приложения.
Примечание. После настройки Nginx необходимо защитить трафик на сервер с помощью SSL/TLS. Это важно, поскольку в противном случае вся информация, включая пароли, будет отправляться через сеть в простом текстовом формате.
Если у вас имеется доменное имя, проще всего будет использовать Let’s Encrypt для получения сертификата SSL для защиты вашего трафика. Следуйте указаниям этого руководства, чтобы настроить Let’s Encrypt с Nginx в Ubuntu 18.04. Следуйте процедуре, используя серверный блок Nginx, созданный нами в этом обучающем модуле.
Если у вас нет доменного имени, вы можете защитить свой сайт для тестирования и обучения с помощью сертификата SSL с собственной подписью. Следуйте процедуре, используя серверный блок Nginx, созданный нами в этом обучающем модуле.
Если на последнем шаге не будет показано ваше приложение, вам нужно будет провести диагностику и устранение неисправностей установки.
Если Nginx показывает страницу по умолчанию, а не выводит ваше приложение через прокси, это обычно означает, что вам нужно изменить параметр server_name
в файле /etc/nginx/sites-available/myproject
, чтобы он указывал на IP-адрес или доменное имя вашего сервера.
Nginx использует server_name
, чтобы определять, какой серверный блок использовать для ответа на запросы. Если вы увидите страницу Nginx по умолчанию, это будет означать, что Nginx не может найти явное соответствие запросу в серверном блоке и выводит блок по умолчанию, заданный в /etc/nginx/sites-available/default
.
Параметр server_name
в серверном блоке вашего проекта должен быть более конкретным, чем содержащийся в серверном блоке, выбираемом по умолчанию.
Ошибка 502 означает, что Nginx не может выступать в качестве прокси для запроса. Ошибка 502 может сигнализировать о разнообразных проблемах конфигурации, поэтому для диагностики и устранения неисправности потребуется больше информации.
В первую очередь эту информацию следует искать в журналах ошибок Nginx. Обычно это указывает, какие условия вызвали проблемы во время прокси-обработки. Изучите журналы ошибок 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
, сгенерированным блоком systemd gunicorn.socket
.
Если вы не можете найти файл gunicorn.sock
в каталоге /run
, это означает, что файл сокета systemd не смог его создать. Вернитесь к разделу проверки файла сокета Gunicorn и выполните процедуру диагностики и устранения неисправностей Gunicorn.
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
Outputf: /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 может вывести сообщение следующего вида:
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
.
В случае обнаружения дополнительных проблем журналы могут помочь в поиске первопричин. Проверяйте их по очереди и ищите сообщения, указывающие на проблемные места.
Следующие журналы могут быть полезными:
sudo journalctl -u nginx
sudo less /var/log/nginx/access.log
sudo less /var/log/nginx/error.log
sudo journalctl -u 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, протестируйте конфигурацию и Nginx с помощью следующей команды:
- sudo nginx -t && sudo systemctl restart nginx
Эти команды помогают адаптироваться к изменениям в случае изменения конфигурации.
В этом руководстве мы создали и настроили проект Django в его собственной виртуальной среде. Мы настроили Gunicorn для трансляции запросов клиентов, чтобы Django мог их обрабатывать. Затем мы настроили Nginx в качестве обратного прокси-сервера для обработки клиентских соединений и вывода проектов, соответствующих запросам клиентов.
Django упрощает создание проектов и приложений, предоставляя множество стандартных элементов и позволяя сосредоточиться на уникальных. Используя описанную в этой статье процедуру, вы сможете легко обслуживать создаваемые приложения на одном сервере.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Добрый день, а в команде:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
путь до модуля wsgi может состоять не из одной папки? В моей задаче фактически команда имеет вид:
gunicorn 32-crud.stocks_products.wsgi:application --bind 0.0.0.0:8001
но почему-то при выполнении stocks_products не находится, в логе написано ModuleNotFoundError: No module named ‘stocks_products’, хотя папка совершенно точно лежит внутри 32-crud. В связи с этим вопрос, здесь ограничение на глубину вложенности, или какой-то специальный синтаксис надо использовать? Или еще что-то, что я даже не могу себе представить? :)
That’s an incredible walkthrough, thanks!
It can be only me, but when I set my /static/ location as it is described here, I can see /static/static/ path requests in my nginx log.
However, if I put it like this:
I have no problems with my static content, assuming that I have
static
dir inmy-project-dir
and all permissions are correctИнструкция очень помогла, впервые вижу такую точную пошаговую статью, сэкономила мне кучу времени, большое спасибо автору!
При выполнении команды sudo systemctl start gunicorn.socket возникает ошибка System has not been booted with systemd as init system (PID 1). Can’t operate. Failed to connect to bus: Host is down
This article really helps me a lot! Thanks!)
Примечание. В интерфейсе администратора не будут применяться в стили, поскольку Gunicorn неизвестно, как находить требуемый статичный контент CSS.
Друзья, каким образом это можно исправить?
Пытаюсь установить Django 3.0.4 на сервере Ubuntu Server 18.04 LTS (HVM), 64-bit (x86) При выполнении команды
~/myprojectdir/manage.py makemigrations
выдаетNo changes detected
. Пробовал указывать вINSTALLED_APPS
название проекта, нo не помогло.