Как создать сервер Django под управлением uWSGI, NGINX и PostgreSQL на AWS EC2 с помощью Python 3.6

1656552854 kak sozdat server django pod upravleniem uwsgi nginx i postgresql

Содержание статьи

от Сумита Кумара

1*RoxYjB7zefsqzjUMLLaprQ

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

Если у вас нет настроения читать, вы можете скопировать, вставить каждый шаг, как описано (заменить значение) и запустить свой сервер?

Предпосылки:

  1. Экземпляр Amazon Linux EC2 запущен и работает со связанной парой ключей (Ssh доступ к нему).
  2. Порт 22, 80 должно быть открытым для этого случая.
  3. Программа Django, которую вы хотите развернуть.
  4. Параметры базы данных настроены на использование PostgreSQL.
  5. требования.txt присутствует в вашем приложении, имеет список зависимостей для установки.
  6. Git репозиторий для вашей программы Django.

SSH и обновление экземпляра Ubuntu

Вам нужно зайти с помощью ssh в свой экземпляр EC2, поэтому убедитесь, что у вас есть порт 22 откройте для своего экземпляра и выполните обновление/обновление.

ssh -i path-to-your-key.pem ubuntu@your-aws-instance-public-ip

sudo apt-get update && sudo apt-get upgrade -y

Установка Python3.6.x на AWS EC2 (ubuntu 16.04)

Мы загрузим tar.xz файл с официального сайта, а затем установите его вручную. Перед этим нам необходимо установить некоторые необходимые зависимости.

Создание и установление зависимостей

sudo apt install build-essential checkinstall

sudo apt install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev

Загрузка и установка вручную необходимой версии Python

cd /opt && sudo wget 

sudo tar -xvf Python-3.6.6.tar.xz

cd Python-3.6.6/

sudo ./configure

sudo make && sudo make install

Удаление загруженного файла

sudo rm -rf Python-3.6.6.tar.xz

Проверьте версию Python

python3 -V
> Python 3.6.6

Настройки пользователя Ubuntu для нашей программы

Django сам по себе очень безопасный фреймворк, я согласен. Но веб-приложения все еще уязвимы. Рекомендуется запускать приложение как пользователи системы с ограниченными привилегиями, которые имеют ограниченный доступ к ресурсам на вашем сервере. Поэтому в этом разделе мы добавим нового пользователя и группу разрешений к нашему экземпляру EC2.

Добавление системной группы Ubuntu «название группы» [webapps in my case] и назначить пользователя «имя пользователя» [bunny in my case] в эту группу

sudo groupadd --system webapps
sudo useradd --system --gid webapps --shell /bin/bash --home /webapps/project_name bunny

Примечание: я предполагаю «Название проекта«- это имя, которое вы могли использовать во время»django-admin startprojectя>”

Создайте каталог для хранения вашей программы

Создайте каталог для хранения вашего приложения в /webapps/project_name/. Измените владельца этого каталога на пользователя вашего приложения bunny:

sudo mkdir -p /webapps/project_name/

sudo chown bunny /webapps/project_name/

Разрешить ограниченный доступ другим пользователям группы в каталог программ

sudo chown -R bunny:users /webapps/project_name

sudo chmod -R g+w /webapps/project_name

Теперь вы можете переключиться на своего пользователя

sudo su - bunny

// your console will switch to something like this
bunny@ip-172-31-5-231:~$

Чтобы вернуться назад к sudo пользователь, просто сделайте ctrl+d и это убьет пользовательский терминал.

Установка и настройка PostgresSQL

Установка PostgreSQL и создание базы данных

sudo apt install postgresql postgresql-contrib

sudo su - postgres

postgres@ip-172-31-5-231:~$ psql

postgres=# CREATE DATABASE database_name;

Изменение пароля по умолчанию для postgre при входе psql терминал

postgres=# \password

Разверните программу Django на экземпляре EC2 через Git в виртуальной среде

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

Использование концепции среды удобно, когда вы разворачиваете несколько приложений Django в одном экземпляре, чтобы сохранить их и их зависимости изолированы друг от друга.

Мы создадим виртуальную среду пользователя нашей системы (зайчик) каталог. Перед этим мы установим git как a sudo пользователь.

Установка Git и извлечение кода из репозитории git

sudo apt-get install git

sudo su - bunny

// change to your repo https or ssh link
bunny@ip-172-31-5-231:~$ git remote add origin 

git@github.com:<user>/<user-repo>.git

bunny@ip-172-31-5-231:~$ git pull origin <branch_name>

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

Создание виртуальной среды с помощью Python3.6 в текущем каталоге

bunny@ip-172-31-5-231:~$ python3.6 -m venv .
bunny@ip-172-31-5-231:~$ source bin/activate
(project_name)bunny@ip-172-31-5-231:~$ pip install -r requirements.txt

Сейчас мы успешно создали наш проект. Теперь нам нужно немного запустить управлять.пy команда. Для этого нужно, чтобы мы находились в каталоге, где присутствует наш manage.py, или всякий раз, когда нам нужно указать путь к нему:

(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py migrate

(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py createsuperuser

(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py collectstatic

Примечание: collectstatic команда требует, чтобы конфигурация STATIC была правильно настроена. Однако мы не обсуждаем это здесь, потому что это не входит в рамки этого учебника.

(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py runserver 0.0.0.0:8000

Это запустит сервер разработки на порту 8000. Предполагая, что порт 8000 также открыт для вашего экземпляра, вы можете посетить доменное имя или IP-адрес вашего сервера, а затем 8000 в вашем браузере.

http://your_server_domain_or_public_IP:8000
http://your_server_domain_or_public_IP:8000/admin

Примечание. Не забудьте добавить свой домен или IP-адрес в ALLOWED_HOST в файле settings.py

Настройка сервера приложений uWSGI

Теперь, когда наш проект сконфигурирован и готов к работе, мы можем настроить uWSGI для размещения нашей программы в Интернете вместо легкого сервера разработки, предоставленного Django.

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

Вы можете установить uWSGI в virtualenv или глобально и настроить его соответственно.

В этом учебнике мы будем устанавливать uWSGI virtualenv. Прежде чем мы сможем установить uWSGI, нам нужны файлы Python, на которые полагается программное обеспечение.

Установка uWSGI вместе с его зависимостями

sudo apt-get install python3-dev
sudo su - bunny
bunny@ip-172-31-5-231:~$ source bin/activate
(project_name)bunny@ip-172-31-5-231:~$ pip install uwsgi

Давайте запустим сервер с помощью uWSGI. Эта команда выполняет то же самое: a manage.py runserver сделал бы. Вам нужно соответственно заменить значение, чтобы успешно проверить эту команду.

(project_name)bunny@ip-172-31-5-231:~$ uwsgi --http :8000 --home <path-to-virtualenv> --chdir <path-to-manage.py-dir> -w <project-name>.wsgi

Создание конфигурационного файла uWSGI

Запуск uWSGI из командной строки полезен только для тестирования. Для фактического развертывания мы создадим a .ini файл где-то в каталоге пользователя системы. Этот файл будет содержать всю конфигурацию для обработки большой загрузки запросов и может быть соответственно сконфигурирован.

Далее в этом учебнике мы будем запускать uWSGI по NGINX. NGINX очень совместим с uWSGI и имеет встроенную поддержку для взаимодействия с uWSGI.

Создайте каталог конф в системном каталоге пользователя, где вы будете хранить uwsgi.ini

(project_name)bunny@ip-172-31-5-231:~$ mkdir conf
(project_name)bunny@ip-172-31-5-231:~$ cd conf
(project_name)bunny@ip-172-31-5-231:~$ nano uwsgi.ini

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

ПРИМЕЧАНИЕ: updateMe должно быть название вашего проекта. Это то же имя, которое вы дали выше при создании каталога пользователя, поэтому обновите его соответственно.

[uwsgi]

# telling user to execute file
uid = bunny

# telling group to execute file
gid = webapps

# name of project you during "django-admin startproject <name>"
project_name = updateMe

# building base path to where project directory is present [In my case this dir is also where my virtual env is]
base_dir = /webapps/%(project_name)

# set PYTHONHOME/virtualenv or setting where my virtual enviroment is
virtualenv = %(base_dir)

# changig current directory to project directory where manage.py is present
chdir = %(base_dir)/src/

# loading wsgi module
module =  %(project_name).wsgi:application

# enabling master process with n numer of child process
master = true
processes = 4

# enabling multithreading and assigning threads per process
# enable-threads  = true
# threads = 2

# Enable post buffering past N bytes. save to disk all HTTP bodies larger than the limit $
post-buffering = 204800

# Serialize accept() usage (if possibie).
thunder-lock = True


# Bind to the specified socket using default uwsgi protocol.
uwsgi-socket = %(base_dir)/run/uwsgi.sock

# set the UNIX sockets’ permissions to access
chmod-socket = 666

# Set internal sockets timeout in seconds.
socket-timeout = 300

# Set the maximum time (in seconds) a worker can take to reload/shutdown.
reload-mercy = 8

# Reload a worker if its address space usage is higher than the specified value (in megabytes).
reload-on-as = 512

# respawn processes taking more than 50 seconds
harakiri = 50

# respawn processes after serving 5000 requests
max-requests = 5000

# clear environment on exit
vacuum = true

# When enabled (set to True), only uWSGI internal messages and errors are logged.
disable-logging = True

# path to where uwsgi logs will be saved
logto = %(base_dir)/log/uwsgi.log

# maximum size of log file 20MB
log-maxsize = 20971520

# Set logfile name after rotation.
log-backupname = %(base_dir)/log/old-uwsgi.log

# Reload uWSGI if the specified file or directory is modified/touched.
touch-reload = %(base_dir)/src/

# Set the number of cores (CPUs) to allocate to each worker process.
# cpu-affinity = 1

# Reload workers after this many seconds. Disabled by default.
max-worker-lifetime = 300

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

Нам нужно создать файл журнала и запустить каталог, где будет создан наш файл сокета, о котором мы только что упоминали в нашем uwsgi.ini:

(project_name)bunny@ip-172-31-5-231:~$ mkdir log
(project_name)bunny@ip-172-31-5-231:~$ mkdir run
(project_name)bunny@ip-172-31-5-231:~$ touch log/uwsgi.log

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

$ sudo chmod 777 /webapps/updateMe/run
$ sudo chmod 777 /webapps/updateMe/log

Теперь попробуем запустить сервер с помощью uwsgi.ini что мы только что создали.

(project_name)bunny@ip-172-31-5-231:~$ uwsgi --ini /webapps/updateMe/conf/uwsgi.ini

Если все до этого момента настроено правильно, значит он должен работать. Если нет, вам нужно вернуться, чтобы проверить, что вы пропустили (например, путь/название проекта и т.д.).

Чтобы проверить любой журнал uswgi, который вы можете кит или хвост uwsgi.log:

(project_name)bunny@ip-172-31-5-231:~$ tail log/uwsgi.log

Создайте файл systemd Unit для uWSGI

На данный момент, если все круто, вы можете даже запустить эту команду на экране и отсоединить ее – но опять же это совсем не лучшая практика. Вместо этого мы создадим системный сервис и разрешим systemd (Менеджер служб Ubuntu) позаботьтесь об этом.

Вернитесь к пользователю sudo

$ sudo nano /etc/systemd/system/uwsgi.service

и скопируйте код вставки из приведенной ниже сущности. Не забудьте обновить и перекрестно проверить имена/путь, подходящие для программы:

[Unit]
Description=uWSGI instance to serve updateMe project
After=network.target

[Service]
User=bunny
Group=webapps
WorkingDirectory=/webapps/project_name/src
Environment="PATH=/webapps/project_name/bin"
ExecStart=/webapps/project_name/bin/uwsgi --ini /webapps/project_name/conf/uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

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

Перезагрузите демон systemctl, чтобы перезагрузить конфигурацию менеджера systemd и воспроизвести все зависимое дерево.

$ sudo systemctl daemon-reload

Включите службу uwsgi для запуска при перезагрузке системы

$ sudo systemctl enable uwsgi

Запустите службу uwsgi

$ sudo service uwsgi start

Перезапустите службу uwsgi

$ sudo service uwsgi restart

Проверьте статус службы uwsgi

$ sudo service uwsgi status

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

Далее мы настроим NGINX и тогда мы закончим! Я знаю, что это займет немного времени, но поверьте мне, как только это сделаете, вы будете так же счастливы, как и я после публикации этого учебника.

Настройка NGINX на EC2 для uWSGI

NGINX – это легкий сервер, и мы будем использовать его как обратный прокси-сервер.

Мы могли бы позволить uWSGI работать непосредственно на порту 80, но NGINX имеет гораздо больше преимуществ, что делает его желанным. Также NGINX первоначально включает поддержку uWSGI.

Достаточно говорить, давайте установим NGINX на наш экземпляр

$ sudo apt-get install nginx

Теперь, когда пойдешь в http://your-public-ip-or-address, вы увидите страницу приветствия Nginx. Это потому, что NGINX прослушивает порт 80 в соответствии с конфигурацией по умолчанию.

NGINX имеет два каталога, сайты-доступны и с поддержкой сайтов, требующих нашего внимания. сайты-доступны сохраняет все файлы conf для всех доступных сайтов в данном конкретном экземпляре. с поддержкой сайтов сохраняет символическую ссылку для каждого активированного сайта в каталог sites-available.

По умолчанию существует только один файл conf с именем default, который имеет базовые настройки для NGINX. Вы можете изменить его или создать новый. В нашем случае я собираюсь удалить его:

$ sudo rm -rf /etc/nginx/sites-available/default
$ sudo rm -rf /etc/nginx/sites-enabled/default

Давайте создавать свою nginx-uwsgi.conf файл для подключения запроса браузера к серверу uwsgi, который мы запускаем на сайте:

$ sudo nano /etc/nginx/sites-available/nginx-uwsgi.conf

и скопируйте следующий код по существу ниже:

upstream updateMe_dev {
    server unix:/webapps/updateMe/run/uwsgi.sock;
}

server {
    listen 80;
    server_name your-IP-or-address-here;
    charset utf-8;

    client_max_body_size 128M;

    location /static {
    # exact path to where your static files are located on server 
    # [mostly you won't need this, as you will be using some storage service for same]
        alias /webapps/updateMe/static_local;
    }

    location /media {
    # exact path to where your media files are located on server 
    # [mostly you won't need this, as you will be using some storage service for same]
        alias /webapps/updateMe/media_local;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass updateMe_dev;
        uwsgi_read_timeout 300s;
        uwsgi_send_timeout 300s;
    }

    access_log /webapps/updateMe/log/dev-nginx-access.log;
    error_log /webapps/updateMe/log/dev-nginx-error.log;
}
$ sudo ln -s /etc/nginx/sites-available/nginx-uwsgi.conf /etc/nginx/sites-enabled/nginx-uwsgi.conf

Вот и все, мы почти на месте, вот-вот закончим…

Перезагрузите демон systemctl

$ sudo systemctl daemon-reload

Включите службу nginx при перезагрузке системы

$ sudo systemctl enable nginx

Запустите службу Nginx

$ sudo service nginx start

Тестирование Nginx. Он должен вернуть OK, успешно как часть результата.

$ sudo nginx -t

Если NGINX дает сбой, вы можете проверить его последний журнал ошибок или журнал доступа по пути, указанному нами в его конфигурации.

$ tail -f /webapps/updateMe/log/nginx-error.log
$ tail -f /webapps/updateMe/log/nginx-access.log

Перезапустите службу Nginx

$ sudo service nginx restart

Проверьте статус службы Nginx

$ sudo service nginx status

Теперь вы сможете получить доступ к своему приложению по адресу http://your-public-ip-or-address

Вот и конец этого длинного учебника. Надеюсь, вы получили от него то, что ожидали. Спасибо за терпение.

PS: uWSGI+NGINX+Django легко настраивается для удовлетворения любых требований большого масштаба. При этом оптимизация ядра по-прежнему лежит на уровне программы. То, как вы кодируете и используете Django ORM или Raw SQL-запрос, поможет вам дальше.

Добавить комментарий

Ваш адрес email не будет опубликован.