Linux nginx postgresql python

Настройка Debian, Nginx и Gunicorn для Django проекта

Была задача поднять свой Debian сервер на Nginx для проектов Django 3.х. Перерыв кучу информации в интернете, удалось это сделать соединив рекомендации с нескольких разных сайтов. Если вам интересно почитать, как настроить свой первый сервер для Django-проекта, то — добро пожаловать.

Немного расскажу о себе, чтобы вы понимали, кто я. Я не разработчик, не программист, не системный администратор и даже не имею IT-образования. Я учитель информатики. Но по работе мне приходится объяснять ученикам некоторые моменты, очень далёкие от школьного курса информатики и один из них это разработка проектов на Django.

Основные установки

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

apt-get update apt-get install -y sudo htop git curl wget unzip zip gcc build-essential make apt-get install -y tree redis-server nginx libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-dev python-pil ython3-pil apt-get install -y python3-lxml libxslt-dev python-libxml2 python-libxslt1 python-dev gnumeric libpq-dev libxml2-dev libxslt1-dev libjpeg-dev libfreetype6-dev libcurl4-openssl-dev supervisor libgdbm-dev libnss3-dev ufw 

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

Далее создаём нового пользователя и добавляем его в группу sudo, чтобы он мог запускать процессы от имени суперпользователя.

adduser username usermod -aG sudo username 

где username — это имя пользователя, которое вы будете использовать в дальнейшем.
Установим последнюю версию Python из исходного кода. На момент написания статьи это была 3.8.2.

cd /home/username curl -O https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz tar -xf Python-3.8.2.tar.xz cd Python-3.8.2 

cd — это команда для изменения рабочего каталога, сокращение от change directory;
curl — позволяет взаимодействовать с различными сервисами по URL. Мы её используем для скачивания файла;
tar — распаковка скаченного архива.

После скачивания последней версии Python и перехода в каталог с исходным кодом мы запускаем:

./configure --enable-optimizations make -j 2 

Это позволит нам подготовить всё необходимое для установки Python. Здесь число 2, это количество ядер процессора. Можно узнать командой nproc.
Запускаем установку.

Проверить, что Python установился, можно командой:

Она выведет версию Python.
После этого обновляем pip и устанавливаем наиболее часто используемые пакеты для Python.

python3.8 -m pip install -U pip python3.8 -m pip install -U setuptools python3.8 -m pip install pillow python3.8 -m pip install virtualenv 

Настройка Django

Перезапускаем систему и заходим под созданным вами пользователем. Перейдём в каталог /var/www и скачаем в него наш проект, который загружен на GitHub.

cd /var/www sudo git clone LINK_TO_PROJECT 
sudo chown -R www-data:www-data /var/www sudo usermod -aG www-data username sudo chmod go-rwx /var/www sudo chmod go+x /var/www sudo chgrp -R www-data /var/www sudo chmod -R go-rwx /var/www sudo chmod -R g+rwx /var/www 

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

Читайте также:  Copy file to same directory linux

Переходим в наш проект, создаём виртуальное окружение и запускаем его:

cd djangoprojectname/ virtualenv env source ./env/bin/activate 

Если всё активировалось, то будет строка вида: (env) username@server.

Поставим/обновим основные пакеты, которые нужны нам для нашего проекта.

pip install -U pip pip install -U setuptools pip install -U pillow 

Ставим Django, Gunicorn и адаптер для PostgreSQL.

pip install django gunicorn psycopg2-binary 

Можно ещё поставить необходимые для вашего проекта пакеты, я использую summernote для текста:

pip install django-summernote

Мы ставили брандмауэр, поэтому нужно создать для него исключение на порт 8000 (его мы используем по умолчанию, если планируете использовать другой, то укажите его):

Обязательный шаг — это проверка работоспособности сервера:

python3.8 manage.py runserver 0.0.0.0:8000

И перейдите на ваш сайт, DOMAIN_NAME:8000, чтобы убедится в том, что всё работает! Но, на данный момент у нас ещё не настроено очень многое, это только базовые настройки, нам нужно настроить нормальную работу сервера, подключить статику и т.д.
Если у Вас не запустился сайт, то нужно копаться в настройках (возможно прав доступа) и смотреть какой из пакетов не установился, тут всё очень индивидуально.

Завершить выполнение можно нажатием клавиш: CTRL+C.

Далее переходим, только если ваш проект запустился, крайне не рекомендую переходить, если что-то не получилось. Лучше устранить проблему на начальном этапе, чем потом сносить сервер под корень (я сносил 3 раза, а потом начал писать эту инструкцию, фиксируя каждое действие).

Проверяем работу Gunicorn:

gunicorn --bind 0.0.0.0:8000 MAINAPPNAME.wsgi

MAINAPPNAME — это имя основного приложения, в котором лежит settings.py.

Если сервер работает, то идём дальше.

Завершить выполнение можно нажатием клавиш: CTRL+C.

Настройка settings.py

При развёртывании на продакшн сервере нужно отключить дебаг у проекта и поменять несколько настроек, я это сделал следующим образом в settings.py моего проекта.

DEBUG = False if DEBUG: ALLOWED_HOSTS = ['*'] else: ALLOWED_HOSTS = ['HOST IP', 'DOMAIN NAIM', 'localhost'] . STATIC_URL = '/static/' if DEBUG: STATIC_DIR = os.path.join(BASE_DIR, 'static') STATICFILES_DIRS = [ STATIC_DIR, '/var/www/static/', ] else: STATIC_ROOT = os.path.join(BASE_DIR, 'static/') STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) MEDIA_URL = '/media/' 

В urls.py я изменил настройки для статики и медиа.

if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 

Я не знаю, насколько это правильное решение и возможно есть более корректные изменения этих файлов. Но в данном случае мне достаточно менять значение DEBUG для того, чтобы переключаться между разработкой и публикацией.

python3.8 manage.py collectstatic 

Для сбора статики и деактивируем виртуальное окружение:

Читайте также:  Linux can ioctl h

Настройка Gunicorn

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

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

[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target

Мы создали раздел [Unit] для описания сокета, в разделе [Socket] мы определили расположение сокета и в разделе [Install] нужен для установки сокета в нужное время.

Откроем служебный файл systemd ля настройки работы сервиса:

sudo nano /etc/systemd/system/gunicorn.service
[Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=username Group=www-data WorkingDirectory=/var/www/djangoprojectname ExecStart=/var/www/djangoprojectname/env/bin/gunicorn \ --access-logfile - \ --workers 5 \ --bind unix:/run/gunicorn.sock \ myproject.wsgi:application [Install] WantedBy=multi-user.target

Не забудьте указать вашего пользователя, ваше название проекта и ваше виртуальное окружение.

Как мне пояснили workers вычисляется как количество ядер процессора * 2 + 1.
Теперь мы запускаем и активируем сокет Gunicorn.

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

И обязательно тестируем, что всё работает!

sudo systemctl status gunicorn.socket

Должен вывести данные о запущенном сервисе.

Нажмите клавишу Q для выхода (обязательно на английской раскладке).

Последняя команда должна вывести сообщение о наличии файла.

Если первая команда sudo systemctl status gunicorn.socket выдаёт ошибку, или если вторая команда file /run/gunicorn.sock сообщит, что в каталоге отсутствует файл gunicorn.sock, то сокет Gunicorn не удалось создать. Нужно проверить журналы сокета Gunicorn с помощью следующей команды:

sudo journalctl -u gunicorn.socket

Смотреть в чём ошибка и устранять.

Перейдём к тестированию активации сокета.

sudo systemctl status gunicorn

Скорее всего у вас будет запись:

Пока всё отлично идём дальше.

Установим соединение с сокетом через curl.

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

Может выдать ошибку Bad Request (400).

Попробуйте вместо localhost указать IP вашего сервера, если всё нормально, то скорее всего это из-за настроек nginx, которые мы ещё не делали. Просто идём дальше.

И снова запросим вывод статуса:

sudo systemctl status gunicorn

Если запись будет такой + ещё масса информации, но не об ошибках, то всё отлично.

Иначе смотрим ошибки в журнале

sudo journalctl -u gunicorn

И перезапускаем процессы Gunicorn

sudo systemctl daemon-reload sudo systemctl restart gunicorn

Настройка NGINX

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

sudo nano /etc/nginx/sites-available/djangoprojectname
server < listen 80; server_name server_domain_or_IP; location = /favicon.ico < access_log off; log_not_found off; >location /static/ < alias /var/www/djangoprojectname/static/; >location /media/ < alias /var/www/djangoprojectname/media/; >location / < include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; >>

В разделе sever_name можно указать несколько адресов через пробел.

Протестируем на наличие ошибок в синтаксисе:

Если ошибок нет, то перезапускаем сервер и даём нашему брандмауэру необходимые права:

sudo systemctl restart nginx sudo ufw allow 'Nginx Full' 

Можно также удалить доступ к порту 8000

sudo ufw delete allow 8000

На этом этапе всё должно работать, но у меня не работало всё нормально, пока я не настроил https. К сожалению, не могу объяснить с чем это связано, но статика не подгружалась, хотя медиа файлы грузились нормально.

Читайте также:  Linux file share software

Настройка HTTPS

Для настройки будем использовать Cerbot

sudo apt-get install certbot python-certbot-nginx sudo certbot –nginx 

И следуем подсказкам на экране. Если появились ошибки, то устраните и повторите. Например, ошибка может возникнуть если вы указали доменное имя, не относящееся к данному серверу.
Для автоматического обновления сертификата введите команду.

sudo certbot renew --dry-run 

Теперь тестим сайт и всё должно работать!

Если статика так и не отобразилась, то попробуйте открыть какой-нибудь css файл указав полный адрес до него, если выдал ошибку 403, то всё отлично, но проблема в правах доступа нужно экспериментировать с ними, попробуйте сбросить все настройки прав для www-data на каталог /var/www. Если ошибка 404, то нужно смотреть в сторону настроек location в настройках NGINX.

Настройка PostgreSQL

Настроим PostgreSQL и сделаем импорт данных из SQLite. Если Вам это не нужно, то пропустите этот шаг, либо возьмите только настройки PostgreSQL.

Создадим базу данных и пользователя.

CREATE DATABASE dbforproject; CREATE USER projectdbuser WITH PASSWORD 'password';

Мы будем следовать рекомендациям по проекту Django.

Зададим кодировку по умолчанию UTF-8, схему изоляции транзакций по умолчанию поставим в «read committed», для блокировки чтение со стороны неподтвержденных транзакций. Часовой пояс поставим в значения времени по Гринвичу (UTC).

ALTER ROLE projectdbuser SET client_encoding TO 'utf8'; ALTER ROLE projectdbuser SET default_transaction_isolation TO 'read committed'; ALTER ROLE projectdbuser SET timezone TO 'UTC';

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

GRANT ALL PRIVILEGES ON DATABASE dbforproject TO projectdbuser;

После выполнения всех команд можно закрыть диалог PostgreSQL с помощью команды:

Теперь настройка PostgreSQL завершена, теперь настроим Django для корректной работы с PostreSQL.

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

cd /var/www/djangoprojectname source ./env/bin/activate cd mainappname/ python3.8 manage.py dumpdata > datadump.json

Поменяем настройки для подключения к базе данных:

Запустите миграцию для БД:

python3.8 manage.py migrate --run-syncdb
>>> from django.contrib.contenttypes.models import ContentType >>> ContentType.objects.all().delete() >>> quit()

И подгрузим ранее выгруженные данные из SQLite:

python3.8 manage.py loaddata datadump.json

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

При написании использовал:

Источник

Оцените статью
Adblock
detector