Django — это бесплатный веб-фреймворк с открытым исходным кодом, написанный на языке программирования Python. Django невероятно быстрый, безопасный и масштабируемый. В руках опытного разработчика Django позволяет быстро создать мощный веб-сайт. Он легко интегрируется с популярными веб-серверами (Apache, Nginx), базами данных (MySQL, MariaDB, PostgreSQL, Oracle, и SQLite), и т. д. Django обеспечивает работу некоторых крупнейших в мире веб-сайтов, таких как Instagram, Mozilla и NASA. Это руководство демонстрирует настройку базовой структуры веб-приложения с помощью Django с PostgreSQL, Nginx и Gunicorn на Ubuntu 20.04.
Предварительные требования
Для выполнения этого руководства вам понадобится сервер Ubuntu 20.04 с настроенным базовым брандмауэром и пользователем без прав root, но с привилегиями sudo. Ознакомьтесь с этим подробным руководством по настройке сервера Ubuntu. Следуйте этому руководству, чтобы настроить пользователя без прав root с привилегиями sudo. Вы также можете настроить брандмауэр Iptables, следуя шагам этого руководства.
Мы будем устанавливать Django в виртуальном окружении. Наличие изолированного окружения для конкретного проекта упрощает управление несколькими проектами на одном сервере. После настройки баз данных и приложений мы развернем сервер приложений Gunicorn. Gunicorn будет выступать в качестве интерфейса приложения, который преобразует клиентские запросы из HTTP в вызовы Python, которые может использовать наше приложение. Затем мы развернем Nginx перед Gunicorn для быстрой обработки соединений и простых в реализации функций безопасности.
Установка необходимых пакетов
Для начала установите все необходимые пакеты. К счастью, все эти пакеты доступны напрямую из официальных репозиториев пакетов Ubuntu. Откройте терминал и обновите кэш пакетов APT:
|
1 |
sudo apt update |
Список пакетов зависит от того, будет ли веб-приложение использовать Python 2 или Python 3. Выполните следующую команду для установки Django с Python 3:
|
1 |
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl |
Django 1.11 LTS — это последний релиз Django с поддержкой Python 2. Если вы планируете использовать Django с Python 2, установите следующие пакеты:
|
1 |
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl |
База данных и пользователь PostgreSQL
В качестве базы данных мы будем использовать PostgreSQL. Это мощная объектно-реляционная система управления базами данных с открытым исходным кодом. PostgreSQL отличается надежностью, стабильностью и производительностью. Подробные инструкции по настройке PostgreSQL см. в этом руководстве по настройке PostgreSQL на сервере Ubuntu. В рамках этого руководства мы настроим выделенную базу данных и пользователя для нашего приложения Django.
По умолчанию PostgreSQL использует схему «peer authentication» (идентификация по имени пользователя ОС) для локальных подключений. Проще говоря, этот метод разрешает вход, если имя пользователя в операционной системе совпадает с именем пользователя PostgreSQL. Во время установки PostgreSQL создает пользователя операционной системы postgres, соответствующего административному пользователю PostgreSQL postgres. Войдите в интерактивную оболочку PostgreSQL от имени пользователя postgres, используя следующую команду:
|
1 |
sudo -u postgres psql |
Вы попадете в командную строку PostgreSQL. Первым шагом будет создание выделенной базы данных для проекта. В качестве примера база данных будет называться viktor_project:
|
1 |
CREATE DATABASE viktor_project; |
Следующим шагом будет создание выделенного пользователя для базы данных проекта. У пользователя должно быть надежное имя. В качестве примера имя пользователя будет viktor_project_user:
|
1 |
CREATE USER viktor_project_user WITH PASSWORD 'password123'; |
Теперь мы изменим некоторые параметры:
- Определенные параметры соединения. Проще говоря, не потребуется запрашивать и устанавливать правильные значения при каждом установлении соединения. Это значительно повышает производительность базы данных.
- Кодировка по умолчанию на
UTF-8. Это универсальная кодировка, и Django ожидает именно ее. - Схема изоляции транзакций по умолчанию «read committed». Она блокирует чтение из незафиксированных транзакций.
- Часовой пояс на
UTC.
Все эти изменения параметров рекомендуются самим проектом Django. Чтобы применить эти изменения, выполните следующие команды. Не забудьте изменить имя пользователя базы данных на правильное:
|
1 2 3 |
ALTER ROLE viktor_project_user SET client_encoding TO 'utf8'; ALTER ROLE viktor_project_user SET default_transaction_isolation TO 'read committed'; ALTER ROLE viktor_project_user SET timezone TO 'UTC'; |
Смените администратора базы данных на выделенного пользователя базы данных:
|
1 |
GRANT ALL PRIVILEGES ON DATABASE viktor_project TO viktor_project_user; |
На этом наша работа с PostgreSQL пока закончена. Выйдите из интерактивной оболочки PostgreSQL:
|
1 |
\q |
Виртуальное окружение Python
После подготовки базы данных мы можем сосредоточиться на настройке остальных требований проекта. Для более простого управления мы создадим виртуальное окружение и установим туда все требования Python. Чтобы создать виртуальное окружение, нам понадобится virtualenv. Его можно легко установить с помощью pip.
Следующие команды обновят pip и установят virtualenv. Для Python 3 выполните следующие команды:
|
1 2 |
sudo -H pip3 install --upgrade pip sudo -H pip3 install virtualenv |
Для Python 2 вместо этого выполните следующие команды:
|
1 2 |
sudo -H pip install --upgrade pip sudo -H pip install virtualenv |
После того как virtualenv будет установлен, придет время создать виртуальное окружение. Далее создайте выделенный каталог для виртуального окружения:
|
1 |
mkdir -v ~/viktor_project |
После этого измените текущий активный каталог на выделенный каталог для виртуального окружения:
|
1 |
cd ~/viktor_project |
Внутри этого каталога выполните следующую команду. Инструмент virtualenv создаст виртуальное окружение с именем проекта:
|
1 |
virtualenv viktor_project |
Будет создан подкаталог с именем проекта. Этот подкаталог будет содержать локальную версию Python и pip. Это обеспечивает гибкость для установки и настройки изолированного окружения Python для проекта.
Следующая команда активирует виртуальное окружение:
|
1 |
source viktor_project/bin/activate |
Приглашение терминала изменится, указывая на то, что вы работаете в виртуальном окружении Python. Теперь, когда мы находимся внутри виртуального окружения, мы установим необходимые требования Python. Нам понадобятся Django, Gunicorn и psycopg2 (адаптер PostgreSQL). Следующая команда укажет локальному pip установить эти компоненты:
|
1 |
pip install django gunicorn psycopg2-binary |
Даже если вы используете Python 3, правильной командой будет pip. Это связано с тем, что внутри виртуального окружения pip3 переименован в pip.
Новый проект Django
После настройки компонентов Python мы можем начать работу непосредственно с файлами проекта Django.
-
Создание проекта Django
Каталог проекта уже создан. Мы укажем Django установить свои файлы туда. Эта процедура создаст каталог второго уровня, содержащий непосредственно код. Каталог также будет содержать сценарий управления. Главное, что мы явно указываем Django целевой каталог, вместо того чтобы позволить ему определять каталог относительно текущего:
|
1 |
django-admin.py startproject viktor_project ~/viktor_project |
Django создаст проект соответствующим образом. Вот некоторые из важных файлов и каталогов, на которых мы сосредоточимся. Имена каталогов и файлов используются в соответствии с демонстрацией.
~/viktor_project/manage.py: Скрипт управления проектом от Django.~/viktor_project/viktor_project/: Это пакет, содержащий проект Django. Он должен содержать файлы __init__.py, settings.py, urls.py, asgi.py и wsgi.py.
-
Настройка параметров проекта
После создания проекта первым делом необходимо настроить его конфигурацию. Откройте settings.py в текстовом редакторе:
|
1 |
nano ~/viktor_project/viktor_project/settings.py |
Первая директива, которую мы ищем, — это ALLOWED_HOSTS. Она определяет серверы или доменные имена, которые могут подключаться к экземпляру Django. Если любой входящий запрос с заголовком Host не соответствует списку ALLOWED_HOSTS, это вызовет исключение. Django рекомендует использовать это для предотвращения определенных типов уязвимостей безопасности:
|
1 |
ALLOWED_HOSTS = ['<server_ip_or_domain_name_1>',' server_ip_or_domain_name_2','localhost'] |
Следующий раздел, на котором мы сосредоточимся, — это DATABASE. Он управляет доступом к базе данных. По умолчанию он содержит конфигурацию для СУБД SQLite. Однако для проекта мы будем использовать базу данных PostgreSQL. Django будет использовать адаптер psycopg2 для взаимодействия с PostgreSQL:
|
1 2 3 4 5 6 7 8 9 10 |
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'viktor_project', 'USER': 'viktor_project_user', 'PASSWORD': 'password123', 'HOST': 'localhost', 'PORT': '', } } |
Теперь перейдите в самый конец файла. Добавьте следующие строки, чтобы указать расположение статических файлов. Это поможет Nginx обрабатывать запросы к этим элементам:
|
1 2 |
import os STATIC_ROOT = os.path.join(BASE_DIR, 'static/') |
Наша работа с settings.py на этом завершена. Сохраните файл и закройте редактор.
-
Завершение первоначальной настройки проекта
Теперь мы можем перенести начальную схему базы данных в выделенную базу данных PostgreSQL. Выполните следующую команду:
|
1 2 |
~/viktor_project/manage.py makemigrations ~/viktor_project/manage.py migrate |
Далее нам нужно создать суперпользователя для проекта. Чтобы создать суперпользователя, выполните следующую команду:
|
1 |
~/viktor_project/manage.py createsuperuser |
Соберите все статические файлы в место, которое мы указали в settings.py. Статические файлы будут собраны в отдельный каталог с именем «static» в каталоге проекта:
|
1 |
~/viktor_project/manage.py collectstatic |
Теперь нам нужно поработать с брандмауэром сервера. Если вы следовали руководству по настройке сервера, то у вас уже настроен и активирован UFW. Мы создадим исключение для порта 8000. Это порт по умолчанию, который использует Django. Ознакомьтесь с этим руководством, чтобы узнать больше о основах и использовании брандмауэра UFW.
|
1 |
sudo ufw allow 8000 |
Затем проверьте действие:
|
1 |
sudo ufw status |
Наконец, мы можем протестировать сервер в действии. Запустите сервер разработки Django:
|
1 |
~/viktor_project/manage.py runserver 0.0.0.0:8000 |
Если настройка прошла успешно, сервер разработки Django должен запуститься и принимать входящие запросы. Откройте браузер и перейдите по IP/домену вашего сервера на порту 8000:
|
1 |
http://<server_or_domain>:8000 |
Вы должны попасть на страницу по умолчанию Django. Чтобы получить доступ к панели администратора, добавьте /admin к URL-адресу. Панель администратора доступна только суперпользователю, которого мы создали ранее:
|
1 |
http://<server_or_domain>:8000/admin |
После входа в систему вы попадете в стандартный интерфейс администратора Django:
На этом тестирование завершено. Чтобы остановить сервер, нажмите «Ctrl + C» в окне терминала.
-
Тестирование Gunicorn
Прежде чем выйти из виртуального окружения, мы хотим убедиться, что Gunicorn может обслуживать приложения. Способ проверить это — использовать Gunicorn для загрузки модуля WSGI проекта.
Команда Gunicorn находится в каталоге проекта:
|
1 2 |
cd ~/viktor_project gunicorn --bind 0.0.0.0:8000 viktor_project.wsgi |
Это запустит Gunicorn на том же интерфейсе, на котором работал Django. Мы можем снова протестировать приложение в обычном веб-браузере. Обратите внимание, что к интерфейсу администратора не будут применены стили, так как Gunicorn все еще не знает, как найти статическое содержимое CSS:
|
1 |
http://<server_or_domain>:8000 |
По окончании нажмите «Ctrl + C» в окне терминала, чтобы остановить сервер Gunicorn.
-
Выход из виртуального окружения
Настройка приложения Django завершена. Выполните следующую команду, чтобы выйти из виртуального окружения:
|
1 |
deactivate |
Файлы сокета и службы Gunicorn
Мы убедились, что Gunicorn может взаимодействовать с приложением Django. Однако нам нужен более надежный способ управления сервером приложений. Здесь на сцену выходит systemd. Systemd — одна из самых популярных систем инициализации, доступных в Linux. Вот подробное руководство по тому, как управлять службами и юнитами systemd.
Мы можем создать файлы сокета и службы для Gunicorn, чтобы systemd мог управлять им как службой. При загрузке будет создан сокет Gunicorn. Сокет будет прослушивать входящие соединения. При установлении соединения systemd запустит процессы Gunicorn для его обработки.
-
Сокет Gunicorn
Начнем с создания сокета Gunicorn. Файл необходимо создать с привилегиями sudo:
|
1 |
sudo nano /etc/systemd/system/gunicorn.socket |
Введите следующий код внутрь файла:
|
1 2 3 4 5 6 7 |
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target |
Как видите, код состоит из трех разделов.
[Unit]:Этот раздел описывает сокет.[Socket]:Он определяет расположение сокета.[Install]:Эта часть гарантирует, что systemd создаст сокет в нужное время.
Save the file and close the editor.
-
Служба Gunicorn
Далее мы создадим файл службы для Gunicorn. Как и файл сокета, его также необходимо создать с привилегиями sudo:
|
1 |
sudo nano /etc/systemd/system/gunicorn.service |
Введите следующий код:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=cloudsigma Group=www-data WorkingDirectory=/home/cloudsigma/viktor_project ExecStart=/home/cloudsigma/viktor_project/viktor_project/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ viktor_project.wsgi:application [Install] WantedBy=multi-user.target |
Код содержит несколько разделов:
[Unit]:Этот раздел определяет метаданные и зависимости. Он также описывает запуск только после достижения сетевой цели.[Service]:В этом разделе указываются пользователь и группа, от имени которых будет запускаться процесс. Владельцем группы назначается «www-data», чтобы Nginx мог взаимодействовать с Gunicorn. Здесь также определяются рабочие каталоги и указываются команды запуска.[Install]:Этот раздел сообщает systemd, к чему привязать эту службу, если она включена при загрузке. Она должна запускаться после запуска обычной многопользовательской системы.
Затем сохраните файл и закройте редактор.
-
Включение сокета Gunicorn
Сокет Gunicorn готов к использованию. Таким образом, вы можете выполнить следующие команды. Это запустит и включит сокет. Файл сокета будет создан в /run/gunicorn.sock при загрузке. При подключении к сокету systemd запустит службу Gunicorn для его обработки:
|
1 2 |
sudo systemctl start gunicorn.socket sudo systemctl enable gunicorn.socket |
Проверьте статус сокета Gunicorn:
|
1 |
sudo systemctl status gunicorn.socket |
Теперь проверьте существование файла сокета:
|
1 |
file /run/gunicorn.sock |
Если статус от systemctl указывает на ошибку или файл gunicorn.sock не был найден, это означает, что сокет был создан неправильно. Ознакомьтесь с подробным журналом для поиска подсказок:
|
1 |
sudo journalctl -u gunicorn.socket |
Не забудьте еще раз заглянуть в файл gunicorn.socket на предмет возможных ошибок.
-
Активация сокета
На данный момент мы запустили gunicorn.socket. Однако без запроса на подключение gunicorn.service не активируется. Далее проверьте статус Gunicorn:
|
1 |
sudo systemctl status gunicorn |
Мы можем протестировать механизм активации сокета, отправив запрос на подключение с помощью curl:
|
1 |
curl --unix-socket /run/gunicorn.sock localhost |
Вы должны получить HTML-вывод от приложения. Это указывает на то, что Gunicorn успешно запустился и смог обслужить приложение Django. Проверьте текущий статус службы Gunicorn:
|
1 |
sudo systemctl status gunicorn |
Если наблюдается какое-либо неожиданное поведение или вывод (указывающий на ошибку), ознакомьтесь с подробными журналами для поиска подсказок:
|
1 |
sudo journalctl -u gunicorn |
Если в файл gunicorn.service были внесены изменения, вам необходимо перезагрузить демон, чтобы заново прочитать определение службы. Также потребуется перезапустить службу Gunicorn:
|
1 2 |
sudo systemctl daemon-reload sudo systemctl restart gunicorn |
Настройка Nginx
Теперь мы настроим Nginx для передачи входящего трафика процессу. Сначала создайте новый блок сервера в Nginx:
|
1 |
sudo nano /etc/nginx/sites-available/viktor_project |
Затем введите следующий код:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
server { listen 80; server_name 31.171.250.71; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/cloudsigma/viktor_project; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; } } |
В конфигурации присутствует несколько блоков:
service:Этот блок определяет, что сервер должен прослушивать порт 80 в обычном режиме и отвечать на доменное имя или IP-адрес сервера.location:Это первая запись location. Она определяет, где искать статические ресурсы.location:Это вторая запись location. Этот блок определяет стандартные параметры прокси и способ передачи трафика на сокет Gunicorn.
Сохраните файл и закройте редактор. Свяжите файл с каталогом «sites-enabled» для активации:
|
1 |
sudo ln -s /etc/nginx/sites-available/viktor_project /etc/nginx/sites-enabled |
После этого проверьте, нет ли синтаксических ошибок в конфигурации Nginx:
|
1 |
sudo nginx -t |
Если вы не обнаружили ошибок, перезапустите Nginx, чтобы изменения вступили в силу:
|
1 |
sudo systemctl restart nginx |
Нам нужно снова изменить правила UFW. Нам больше не нужен доступ к серверу разработки, поэтому мы можем удалить исключение для порта 8000. Кроме того, мы хотим открыть порт 80 для обычного трафика:
|
1 2 |
sudo ufw delete allow 8000 sudo ufw allow 'Nginx Full' |
Проверьте изменения правил брандмауэра:
|
1 |
sudo ufw status |
Теперь сервер должен быть доступен из обычного веб-браузера.
Процедуры устранения неполадок
Если все шаги были выполнены правильно, приложение Django должно быть доступно через Интернет. Если это не так, значит, установка прошла не по плану. Нам нужно провести диагностику, чтобы выяснить источник проблемы.
-
Nginx показывает страницу по умолчанию
Если Nginx отображает страницу по умолчанию вместо прокси приложения, обычно это означает, что server_name был неправильно настроен в блоке сервера.
В этом примере блок сервера хранится по следующему пути:
|
1 |
/etc/nginx/sites-available/viktor_project |
Запись server_name определяет, какой блок сервера Nginx будет использовать для ответа на запросы. Если отображается страница по умолчанию, то Nginx, вероятно, не смог сопоставить запрос с конкретным блоком сервера, поэтому вместо этого он возвращается к блоку по умолчанию:
|
1 |
/etc/nginx/sites-available/default |
Проверьте, правильно ли указан server_name.
-
502 Bad Gateway
Ошибка 502 указывает на то, что Nginx не смог успешно проксировать запрос. Существует широкий спектр возможных проблем с конфигурацией, которые могут привести к ошибке 502, поэтому нам нужны подсказки для правильного устранения неполадок.
Основным источником подсказок являются журналы ошибок Nginx. Как правило, они указывают на условия, которые вызвали проблемы во время проксирования. Проверьте журнал ошибок Nginx с помощью следующей команды:
|
1 |
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 в блоке сайта. Проверьте, указывает ли proxy_pass на правильное расположение gunicorn.sock, созданного юнитом systemd gunicorn.socket:
|
1 |
/etc/nginx/sites-available/viktor_project |
Если gunicorn.sock не был найден в каталоге /run, это означает, что systemd не смог его создать. Вам следует еще раз проверить шаги настройки файла сокета Gunicorn.
- connect() to unix:/run/gunicorn.sock failed (13: Permission denied)
Это указывает на то, что Nginx не смог подключиться к сокету Gunicorn из-за проблем с правами доступа. Это может произойти, если процесс выполнялся от имени пользователя root, а не пользователя sudo. Хотя systemd успешно создал gunicorn.sock, Nginx не может его использовать.
Одним из возможных виновников могут быть ограниченные права доступа между корневым каталогом (/) и файлом gunicorn.sock. Проверьте права доступа и владельца файла сокета и каждого из его родительских каталогов:
|
1 |
namei -l /run/gunicorn.sock |
Первый столбец описывает права доступа к файлу. Второй столбец описывает владельца-пользователя, а третий столбец — владельца-группу. Если какой-либо из каталогов, ведущих к gunicorn.sock, не имеет надлежащих прав на чтение и выполнение, Nginx не сможет получить доступ к сокету.
-
Django отображает «could not connect to the server: Connection refused»
Это указывает на то, что Django не удалось подключиться к серверу PostgreSQL. Убедитесь, что сервер PostgreSQL запущен и работает:
|
1 |
sudo systemctl status postgresql |
Если она не запущена, выполните следующие команды для её запуска и добавления в автозагрузку:
|
1 2 |
sudo systemctl start postgresql sudo systemctl enable postgresql |
Если вы всё ещё сталкиваетесь с этой ошибкой, убедитесь, что учётные данные базы данных правильно указаны в settings.py:
|
1 |
~/viktor_project/viktor_project/settings.py |
Дополнительное устранение неполадок
Для дополнительного устранения неполадок предусмотрены различные логи. Эти логи могут помочь сузить круг возможных причин проблем.
Вот список логов, которые могут помочь:
- Логи Nginx
|
1 |
sudo journalctl -u nginx |
- Логи доступа Nginx
|
1 |
sudo less /var/log/nginx/access.log |
- Логи ошибок Nginx
|
1 |
sudo less /var/log/nginx/error.log |
- Логи приложения Gunicorn
|
1 |
sudo journalctl -u gunicorn |
- Логи сокета Gunicorn
|
1 |
sudo journalctl -u gunicorn.socket |
|
1 |
sudo systemctl restart gunicorn |
|
1 2 |
sudo systemctl daemon-reload sudo systemctl restart gunicorn.socket gunicorn.service |
|
1 2 |
sudo nginx -t sudo systemctl restart nginx |
Заключение
В этом руководстве успешно показано, как заложить основу для Django. Django предоставляет множество стандартных компонентов веб-приложения, позволяя вам сосредоточиться на уникальных элементах. Проект Django будет работать в виртуальном окружении. Gunicorn управляет взаимодействием между запросами клиентов и Django. Наконец, Nginx выступает в роли обратного прокси-сервера для обработки клиентских подключений.
Приятной работы!










Комментарии
Комментариев пока нет. Будьте первым.