▌ Описание ⚙️
Проект представляет собой тренировку по сборке приложения из backend и frontend частей.
Рассматриваются варианты локальной сборки и запуска приложения и деплоя на удалённый сервер.
Проект отлично демонстрирует, как работает на практике API взаимодействие между двумя приложениями, написанные на разных языках
- backend - python
- frontend - React
Разобрав этот проект, вы узнаете:
- как собирается web приложение из backend и frontend частей
- что такое Gunicorn и как настраивается автоматический запуск приложения
- что такое Nginx и как настраивается маршрутизация запросов
▌ Установка и запуск 🛠️
Для локального запуска проекта необходимо одновременно запустить django приложение из директории backend и frontend приложение из директории frontend.
Для начала, активируйте виртуальное окружение и установите зависимости из файла requirements.txt
python -m venv venv # Linux | Mac Os
python -m venv venv # Windows
source venv/bin/avtivate # # Linux | Mac Os
. venv/scripts/activate # Windows
pip install -r requirements.txt
- Запуск бэкенда
- Перейдите в директорию /backend
cd backend
- Выполните стандартные шаги по запуску Django приложения
python manage.py migrate # Применение миграций (создание бд)
python manage.py createsuperuser # Создание суперюзера для админки(выполните все предложенные шаги)
python manage.py runserver # Запуск Django приложения
- запуск фронтенда
Для дальнейших шагов необходимо убедиться, что в вашей системе установлено все необхожимые пакеты для работы с Node
Если в вашей системе не установлен npm:
sudo apt install npm # Для Linux
Для windows воспользуйтесь инструкцией на официальном сайте nodejs:
Убедитесь, что npm появился в вашей системе
npm -v
- Перейдите в директорию */frontend
cd frontend
Установите зависимости
npm i
Выполните сборку приложения
npm run build
Запустите фронтенд приложение
nmp start
Приложение станет доступно по адресу http://localhost:3000/signin
Деплой проекта на сервер - достаточно сложная и ресурсоёмкая задача, которая состоит из многих шагов. Далее будут описаны необходимые инструкции и подсказки для настройки проекта на удалённом сервере.
- Подключение к серверу.
Для деплоя проекта на удалённый сервер вам понадобятся данные для доступа (SSH ключ, passphrase, ip)
Убедитесь, что у вас установлен SSH клиент
ssh -V
Для подключения к серверу выполните команду
ssh -i ssh -i путь_до_файла_с_SSH_ключом/название_файла_закрытого_SSH-ключа login@ip
# При корректно введённых данных терминал попросит ввести passphrase:
# Enter passphrase for key
# введите пароль от закрытого SSH-ключа
- Подключение сервера к аккаунту на GitHub
Для этого необходимо выполнить следующие шаги
- Установите на сервер Git.
Обновите список доступных пакетов
sudo apt update
проверьте, есть ли на вашем сервере Git, выполните команду:
git --version
Если гитхаб установлен, в терминале вы увидите что-то в таком роде
git version 2.43.0
Если нет, установите Git
sudo apt-get update # обновите индекс пакетов
sudo apt-get install git # установите git
Ещё раз проверьте, что Git установлен.
- Познакомьте ваш GitHub с вашим удалённым сервером — перенесите публичный SSH-ключ сервера в настройки вашего аккаунта на GitHub.
Сгенерируйте пару SSH-ключей, выведите публичный ключ в консоль, скопируйте его и запишите в настройки вашего аккаунта на GitHub.
Краткая инструкция как генерить SSH:
ssh-keygen
# Консоль попросит ввести путь к файлу, в который будут сохранены сгенерированные ключи,
# и одновременно предложит сохранить их в файл по умолчанию:
# Сохраните файлы с ключами в директорию по умолчанию: для этого нажмите Enter на Windows
# или Return на macOS.
# При создании ключей система попросит придумать пароль для доступа к ключам. Когда вы будете
# задавать пароль, в терминале ничего не отобразится, даже звёздочки:
# Enter passphrase (empty for no passphrase):
# Обязательно создайте пароль и запомните его — это дополнительная мера безопасности на тот
# случай, если ваш приватный ключ попадёт не в те руки.
# Рисунок в окне терминала будет свидетельствовать, что ключи успешно созданы
Теперь необходимо сохранить открытый ключ в вашем аккаунте на GitHub.
Выведите ключ в терминал командой:
cat .ssh/id_rsa.pub
Скопируйте ключ от символов ssh-rsa, включительно, и до конца
Зайдите в свой аккаунт на GitHub, перейдите в раздел настроек
Выберите пункт SSH and GPG keys; для создания нового ключа нажмите на кнопку New SSH key
в правом верхнему углу:
Откроется страница с двумя полями ввода:
Нажмите кнопку Add SSH key — ключ добавится к вашему аккаунту. Если вы захотите получить
SSH-доступ к своему аккаунту на GitHub с нескольких компьютеров, для каждого из них может
быть создан и добавлен свой SSH-ключ.
- Клонируйте проект на сервер.
git clone [email protected]:Ваш_аккаунт/deploy_first_project.git
Далее система попросит вас сохранить отпечаток сервера:
# The authenticity of host 'sample.ssh.com' cannot be established.
# DSA key fingerprint is 04:48:30:31:b0:f3:5a:9b:01:9d:b3:a7:38:e2:b1
# Are you sure you want to continue connecting? (yes/no)?
Введите yes в консоль, нажмите Enter, а потом введите пароль от закрытого SSH-ключа, который вы только что записали в настройки вашего аккаунта на GitHub:
- Запуск приложения на веб-сервере разработки Django
Установите на сервер пакетный менеджер и утилиту для создания виртуального окружения
sudo apt install python3-pip python3-venv -y
Далее проведите стандартную работу с зависимостями
# Переходим в директорию backend-приложения проекта.
cd /backend/
# Создаём виртуальное окружение.
python3 -m venv venv
# Активируем виртуальное окружение.
source venv/bin/activate
# Обновляем pip в виртуальном окружении
pip install --upgrade pip
# Устанавливаем зависимости.
pip install -r requirements.txt
# Применяем миграции.
python manage.py migrate
# Создаём суперпользователя.
python manage.py createsuperuser
Для запуска Django приложения на сервере воспользуйтесь командой python manage.py runserver 0:8000
(Если что-то пошло не так, проверьте список ALLOWED_HOSTS в settings.py)
- Запуск фронтенда
Установить на сервер пакетный менеджер npm
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt install -y nodejs
После установки Node.js сервер, скорее всего, снова попросит перезагрузить операционную систему. Перезагружайте её и двигайтесь дальше. Далее убедитесь, что пакетный менеджер npm тоже установился
npm -v
Перейдите в директорию frontend и установите записимости для фронтенд приложения
npm i
И запустите его
npm run start
Настройка WSGI Gunicorn
WSGI (англ. Web Server Gateway Interface) — стандарт взаимодействия Python-фреймворков и веб-серверов.
Команда запуска Gunicorn
gunicorn --bind 0.0.0.0:8000 kittygram_backend.wsgi
Создайте демона для автоматического запуска Gunicorn В директории /etc/systemd/system/ создайте файл gunicorn.service и откройте его в Nano.
sudo nano /etc/systemd/system/gunicorn.service
Опишите конфигурацию процесса
[Unit]
# Это текстовое описание юнита, пояснение для разработчика.
Description=gunicorn daemon
# Условие: при старте операционной системы запускать процесс только после того,
# как операционная система загрузится и настроит подключение к сети.
# Ссылка на документацию с возможными вариантами значений
# https://systemd.io/NETWORK_ONLINE/
After=network.target
[Service]
# От чьего имени будет происходить запуск:
# укажите имя пользователя, под которым вы подключались к серверу по ssh.
User=aldmal # Поменяйте на ваше имя пользователя
# Путь к директории проекта:
# /home/<имя-пользователя-в-системе>/
# <директория-с-проектом>/<директория-с-файлом-manage.py>/.
# Например:
WorkingDirectory=/home/aldmal/python_projects/learning_projects/deploy_first_project/backend
# Команду, которую вы запускали руками, теперь будет запускать systemd:
# /home/<имя-пользователя-в-системе>/
# <директория-с-проектом>/<путь-до-gunicorn-в-виртуальном-окружении> --bind 0.0.0.0:8000 backend.wsgi
ExecStart=/home/aldmal/python_projects/learning_projects/deploy_first_project/venv/bin/gunicorn --bind 0.0.0.0:8080 kittygram_backend.wsgi
[Install]
# В этом параметре указывается вариант запуска процесса.
# Значение <multi-user.target> указывают, чтобы systemd запустил процесс,
# доступный всем пользователям и без графического интерфейса.
WantedBy=multi-user.target
Пример файла gunicorn.service в директории infra
Чтобы точно узнать путь до Gunicorn, активируйте виртуальное окружение и воспользуйтесь командой which gunicorn
Для запуска демона воспользуйтесь командой
sudo systemctl start gunicorn
Дополнительной командой добавьте процесс Gunicorn в список автозапуска операционной системы на удалённом сервере:
sudo systemctl enable gunicorn
После небольшого ожидания можно будет проверить работоспособность запущенного демона. Для этого воспользуйтесь командой:
sudo systemctl status gunicorn
Проверьте, что демон корректно запустился и проект доступен по адресу http://0.0.0.0:8080/
Настройка вебсервера Nginx
Nginx это Веб- и обратный прокси-сервер.
Прокси-сервер — это посредник между интернетом и пользователем. Он принимает запросы от пользователя и перенаправляет их к серверу, например к серверу приложений. Затем он принимает ответы от сервера и отправляет их клиенту, тем самым скрывая IP-адрес пользователя. Прокси-серверы часто используются для того, чтобы ускорить загрузку веб-страниц за счёт их кеширования, защитить сетевые ресурсы от злоумышленников, и для других целей.
Обратный прокси-сервер — это посредник между интернетом и сервером. Он принимает запросы из интернета и передаёт их одному или нескольким серверам. Для пользователя у этих серверов один и тот же адрес. Затем обратный прокси-сервер принимает ответы от серверов и отправляет их обратно в интернет. Обратный прокси-сервер используется для маршрутизации запросов.
- установка Nginx
Находясь на удалённом сервере, из любой директории выполните команду:
sudo apt install nginx -y
Далее сервер, скорее всего, попросит вас перезагрузить операционную систему — сделайте это. А потом запустите Nginx командой:
sudo systemctl start nginx
Укажите файрволу, какие порты должны остаться открытыми. Для этого выполните на сервере две команды по очереди:
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
Включите его:
sudo ufw enable
- Настройка Nginx
Перейдите в директорию /frontend и выполните команду:
npm run build
Соберите статику фронта если вы ещё не делали этого. Из директории frontend:
npm run build
Чтобы Nginx раздавал статику, он должен знать, где она лежит. У веб-сервера есть системная директория, которую он использует по умолчанию для доступа к статическим файлам, — /var/www/. Скопируйте в эту директорию содержимое папки .../frontend/build/:
# Команда cp — копировать, ключ -r — рекурсивно, включая вложенные папки и файлы.
sudo cp -r /home/ваш_пользователь/deploy_first_project/frontend/build/. /var/www/kittygram/
# Точка после build важна — будет скопировано содержимое директории.
Откройте файл конфигурации веб-сервиса:
sudo nano /etc/nginx/sites-enabled/default
Удалите все настройки из файла, запишите и сохраните новые:
server {
listen 80;
server_name публичный_ip_вашего_удалённого_сервера;
location /api/ {
# Эта команда определяет, куда нужно перенаправить запрос.
proxy_pass http://127.0.0.1:8000;
}
# настройка админ зоны
location /admin/ {
proxy_pass http://127.0.0.1:8000;
}
# настройка для сохранения медиа файлов
location /media/ {
alias /media/;
client_max_body_size 20M;
}
location / {
root /var/www/kittygram;
index index.html index.htm;
try_files $uri /index.html;
}
}
Пример конфигурационного файла из проекта в директории infra Nano — редактор не с самым дружелюбным интерфейсом, поэтому да, чтобы очистить файл, придётся зажать клавишу Backspace. Это самый простой способ справиться с этой задачей. Также можно удалять текст построчно — для этого воспользуйтесь сочетанием клавиш Ctrl+K.
Проверье файл конфигурации на ошибки
sudo nginx -t
Перезагрузите конфигурацию Nginx:
sudo systemctl reload nginx
Если что-то пошло не так в обработке запросов, посмотрите логи. По умолчанию логи хранятся в файлах /var/log/nginx/access.log (лог всех запросов) и /var/log/nginx/error.log (лог ошибочных запросов). Команда для просмотра лога последних запросов:
sudo tail /var/log/nginx/access.log
Если возникла проблема с отображением статики, проверьте переменные в файле settings.py django приложения.
STATIC_URL = '/static_backend/'
STATIC_ROOT = BASE_DIR / 'static_backend'
Если вы ещё не собирали статику django приложения, сделайте это:
python manage.py collectstatic # из директории /backend
# Должна появится директория /static_backend
sudo cp -r /home/ваш_пользователь/deploy_first_project/backend/static_backend/ /var/www/kittygram/
# Обратите внимание, здесь мы копируем всю директорию целиком без ключа .
Чтобы изменения в файле settings.py вступили в силу, перезапустите Gunicorn:
sudo systemctl restart gunicorn
Если все шаги выполнены корректно, проект станет доступен по вашему ip адресу, указанному в настройках конфигурационного файла Nginx.
▌ Автор 📝
Александров Дмитрий
GitHub
Telegram
Habr Career