Развертывание на виртуальном частном сервере
Добро пожаловать в седьмую и последнюю часть этой серии руководств, состоящих из нескольких частей, по полнофункциональной веб-разработке с использованием Vue.js и Flask. В этом посте я продемонстрирую, как развернуть приложение, созданное в этой серии.
Код этого поста можно найти в моей учетной записи GitHub в ветке SeventhPost .
Содержание серии
- Seup и знакомство с VueJS
- Навигация по Vue Router
- Управление состоянием с Vuex
- RESTful API с Flask
- Интеграция AJAX с REST API
- JWT аутентификация
- Развертывание на виртуальном частном сервере (вы здесь)
Обзор технологий
В этом руководстве будут рассмотрены несколько технологий, необходимых для развертывания распределенного многоуровневого REST API Flask и приложения Vue.js SPA. Ниже я перечислил технологии и их использование:
- Ubuntu LTS 16.04: хост-сервер для запуска различных приложений и серверов
- uWSGI: сервер-контейнер интерфейса шлюза веб-сервера (WSGI) для выполнения приложений Python (в данном случае Flask)
- Nginx: высокопроизводительный неблокирующий веб-сервер HTTP, способный выполнять обратное проксирование в uWSGI.
- Node.js / NPM: среда Javascript для создания приложения Vue.js SPA
Подготовка кода к развертыванию
После развертывания приложения в моей производственной среде необходимо внести несколько изменений в код, чтобы сделать его более удобным для сопровождения.
Например, в api / index.js survey-spa
Vue.js я жестко запрограммировал
переменную с именем API_URL
чтобы она указывала на сервер разработки
http://127.0.0.1:5000/api
. При этом мне нужно будет не забыть менять
это на IP-адрес производственного сервера каждый раз, когда мне нужно
будет развернуть.
Опыт научил меня, что всегда будут изменения в приложении, требующие будущих развертываний, когда я, вероятно, забуду обновить этот IP-адрес. Лучшим подходом является устранение риска того, что я забуду обновить это, и вместо этого использую конфигурации в процессе сборки, чтобы справиться с этим для меня, что приведет к тому, что мне нужно помнить меньше (т. Это значительно снижает риск неудачного развертывания будущих обновлений.
Я добиваюсь этого, перейдя в каталог survey-spa / config и изменив файлы
dev.env.js и prod.env.js, определив переменную с именем API_URL
которой присвоено значение http://localhost:5000/api
для dev и
http://${process.env.BASE_URL}/api
для prod, как показано ниже:
// dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
API_URL: JSON.stringify(`http://localhost:5000/api`)
})
// prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"',
API_URL: JSON.stringify(`http://${process.env.BASE_URL}/api`)
}
Примечание : значение process.env.BASE_URL
- это переменная среды,
которую я добавлю к пользователю сервера Ubuntu .bash_profile и
установлю его равным IP-адресу сервера.
Затем в api / index.js я изменяю строку
const API_URL = 'http://127.0.0.1:5000/api'
и устанавливаю ее равной
process.env.API_URL
.
Затем в приложении Flask мне нужно добавить новый модуль с именем
wsgi.py, который будет служить точкой входа в REST API Flask. Модуль
wsgi.py выглядит очень похоже на модуль appserver.py за исключением
того, что он не имеет никаких вызовов run(...)
объекта приложения. Это
связано с тем, что объект приложения будет служить вызываемым сервером
контейнера uwsgi для выполнения с использованием его быстрого двоичного
протокола, а не обычного сервера разработки, который создается при
app.run(...)
.
# backend/wsgi.py
from surveyapi.application import create_app
app = create_app()
Закончив с этим, я могу отправить свои изменения в систему управления версиями и перейти на рабочий сервер, чтобы развернуть проект и настроить программы, которые я буду использовать для запуска приложения на производственном сервере.
Подготовка сервера Ubuntu
Затем я перейду к своему производственному виртуальному частному серверу Ubuntu, который может быть размещен в одном из множества облачных сервисов, таких как AWS, DigitalOcean, Linode и т. Д., И начну установку всех полезных функций, перечисленных в Обзоре технологий. раздел.
$ apt-get update
$ apt-get install python3-pip python3-dev python3-venv nginx nodejs npm
После этих установок я теперь могу создать пользователя с именем «survey» для выполнения приложения и размещения кода.
$ adduser survey
$ usermod -aG sudo survey
$ su survey
$ cd
Теперь я должен быть в домашнем каталоге пользователя "Survey" в / home / survey.
Создав пользователя опроса, я могу обновить файл .bash_profile, чтобы он содержал IP-адрес моего рабочего сервера, добавив эту строку в конец файла. Обратите внимание, что 123.45.67.89 представляет собой поддельный IP-адрес моего сервера. Замените его своим истинным IP-адресом, если вы следите за ним.
export BASE_URL=123.45.67.89
Затем я хочу сообщить брандмауэру ( ufw ), что OpenSSH приемлем, и включить его.
$ sudo ufw allow OpenSSH
$ sudo ufw enable
После этого я клонирую репозиторий на сервер, чтобы я мог его собрать и развернуть.
$ git clone https://github.com/amcquistan/flask-vuejs-survey.git
Теперь я перейду в flask-vuejs-survey / frontend / survey-spa и установлю зависимости внешнего интерфейса, а также создам производственное приложение.
$ cd flask-vuejs-survey/frontend/survey-spa
$ npm install
$ npm run build
Это создает новый каталог с именем «dist», который будет содержать страницу index.html и каталог с именем «static», содержащий все скомпилированные файлы CSS и JavaScript. Это то, что у меня будет сервер Nginx, чтобы составить интерфейсное приложение SPA.
Далее я создам виртуальную среду в каталоге / home / survey для изолированного интерпретатора Python3 для запуска приложения Python. После установки я активирую его и перехожу в каталог внутреннего проекта, чтобы установить его пакеты зависимостей, указанные в файле requirements.txt.
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ cd flask-vuejs-survey/backend
(venv) $ pip install -r requirements.txt
Теперь я могу инициализировать базу данных sqlite и запустить миграции для создания различных таблиц базы данных, необходимых для REST API.
(venv) $ python manage.py db upgrade
На этом этапе я хотел бы запустить сервер разработки Flask, чтобы
убедиться, что все работает должным образом. Перед тем, как сделать это,
мне нужно сообщить ufw
чтобы она разрешила трафик через порт 5000.
(venv) $ sudo ufw allow 5000
(venv) $ python appserver.py
Теперь в браузере я могу перейти на
http://123.45.67.89:5000/api/surveys/
и я должен увидеть простой ответ
JSON []
потому что в этой базе данных еще нет опросов, но это
означает, что успешный запрос был сделан. Кроме того, в терминале,
подключенном к серверу, должно быть зарегистрированное сообщение для
запроса GET, отправленного из моего браузера.
Я нажимаю Ctrl + C в терминале, чтобы убить сервер Flask dev, и перехожу к настройке uwsgi для управления выполнением моего Flask REST API. Если вам интересно, откуда взялся uwsgi, он указан как требование в файле requirements.txt, который я установил ранее.
Настройка сервера контейнера uWSGI
Подобно тому, что я только что сделал с сервером разработки Flask, теперь я проверю, может ли сервер uWSGI обслуживать приложение следующим образом.
(venv) $ uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
Опять же, переход в свой браузер и обновление того же запроса, который я сделал ранее, должен вернуть пустой ответ массива JSON. Как только я доволен своим прогрессом, я могу снова нажать Ctrl + C в терминале и двигаться дальше.
Есть еще два шага, которые я хотел бы сделать, чтобы завершить настройку сервера контейнера uWSGI. Один шаг - создать файл конфигурации, который будет читать uWSGI, который заменит многие из тех флагов и аргументов командной строки, которые я использовал выше. Второй шаг - создать служебный файл systemd для управления сервером контейнера uWSGI как службой, как и многие другие, уже запущенные на сервере Ubuntu.
В каталоге backend я создаю файл с именем surveyapi.ini и заполняю его следующим:
[uwsgi]
module = wsgi:app
master = true
processes = 4
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
Этот файл конфигурации позволяет uWSGI знать, что вызываемый объект -
это объект приложения внутри модуля wsgi.py. Он также сообщает ему
создать и использовать четыре процесса для обработки запросов
приложений, передаваемых через файл сокета под названием Surveyapi.sock,
который имеет достаточно свободные права, позволяющие веб-серверу Nginx
читать и писать из него. Настройки vacuum
и die-on-term
службы
должны обеспечивать надлежащую очистку.
Для служебного файла systemd мне нужно создать файл с именем
surveyapi.service
в каталоге / etc / systemd / system и добавить
несколько дескрипторов, а также команды доступа, записи и выполнения,
например:
(venv) $ sudo nano /etc/systemd/system/surveyapi.service
Затем заполните его следующим:
[Unit]
Description=uWSGI Python container server
After=network.target
[Service]
User=survey
Group=www-data
WorkingDirectory=/home/survey/flask-vuejs-survey/backend
Environment="PATH=/home/survey/venv/bin"
ExecStart=/home/survey/venv/bin/uwsgi --ini surveyapi.ini
[Install]
WantedBy=multi-user.target
Теперь я могу запустить службу и проверить ее статус, а также убедиться, что в внутреннем каталоге теперь есть surveyapi.sock.
(venv) $ sudo systemctl start surveyapi
(venv) $ sudo systemctl status surveyapi
Loaded: loaded (/etc/systemd/system/surveyapi.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2018-04-23 19:23:01 UTC; 2min 28s ago
Main PID: 11221 (uwsgi)
Tasks: 6
Memory: 28.1M
CPU: 384ms
CGroup: /system.slice/surveyapi.service
├─11221 /home/survey/venv/bin/uwsgi --ini surveyapi.ini
├─11226 /home/survey/venv/bin/uwsgi --ini surveyapi.ini
├─11227 /home/survey/venv/bin/uwsgi --ini surveyapi.ini
├─11228 /home/survey/venv/bin/uwsgi --ini surveyapi.ini
├─11229 /home/survey/venv/bin/uwsgi --ini surveyapi.ini
└─11230 /home/survey/venv/bin/uwsgi --ini surveyapi.ini
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: mapped 437520 bytes (427 KB) for 5 cores
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: *** Operational MODE: preforking ***
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x8b4c30 pid: 112
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: *** uWSGI is running in multiple interpreter mode ***
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: spawned uWSGI master process (pid: 11221)
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: spawned uWSGI worker 1 (pid: 11226, cores: 1)
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: spawned uWSGI worker 2 (pid: 11227, cores: 1)
Apr 23 19:23:01 ubuntu-s-1vcpu-2gb-sfo2-01 uwsgi[11221]: spawned uWSGI worker 3 (pid: 11228, cores: 1)
lines 1-23
(venv) $ ls -l /home/survey/flask-vuejs-survey/backend
-rw-rw-r-- 1 survey survey 201 Apr 23 18:18 appserver.py
-rw-rw-r-- 1 survey survey 745 Apr 23 17:55 manage.py
drwxrwxr-x 4 survey survey 4096 Apr 23 18:06 migrations
drwxrwxr-x 2 survey survey 4096 Apr 23 18:52 __pycache__
-rw-rw-r-- 1 survey survey 397 Apr 23 18:46 requirements.txt
drwxrwxr-x 3 survey survey 4096 Apr 23 18:06 surveyapi
-rw-rw-r-- 1 survey survey 133 Apr 23 19:04 surveyapi.ini
srw-rw---- 1 survey www-data 0 Apr 23 19:23 surveyapi.sock
-rw-r--r-- 1 survey survey 10240 Apr 23 18:19 survey.db
-rw-rw-r-- 1 survey survey 84 Apr 23 18:42 wsgi.py
Отлично! Последнее, что мне нужно сделать, это включить автоматический запуск каждый раз при загрузке системы, чтобы приложение всегда работало.
(venv) $ sudo systemctl enable surveyapi
Настройка Nginx
Я буду использовать Nginx для обслуживания статического контента, такого как HTML, CSS и JavaScript, а также для обратных вызовов REST API прокси для приложения Flask / uWSGI. Чтобы настроить nginx для выполнения этих задач, мне нужно будет создать файл конфигурации, который определяет, как управлять этими различными запросами.
В / etc / nginx / sites-available я создам файл под названием survey, который будет содержать следующее:
server {
listen 80;
server_name 123.45.67.89;
location /api {
include uwsgi_params;
uwsgi_pass unix:/home/survey/flask-vuejs-survey/backend/surveyapi.sock;
}
location / {
root /home/survey/flask-vuejs-survey/frontend/survey-spa/dist;
try_files $uri $uri/ /index.html;
}
}
Этот файл создает новую конфигурацию серверного блока, в которой говорится, что нужно прослушивать IP-адрес 123.45.67.89 на стандартном HTTP-порту 80. Затем он говорит, что нужно искать любые пути URI, начинающиеся с / api, и обратный прокси-сервер, ведущий к серверу Flask / uWSGI REST API. используя ранее определенный файл сокета. Наконец, конфигурация говорит, что нужно поймать все остальное в / и обслуживать файл index.html в каталоге dist, созданном, когда я ранее создавал интерфейсное приложение SPA Vue.js.
Создав этот файл конфигурации, мне нужно сообщить Nginx, что это доступный сайт, создав символическую ссылку на каталог / etc / nginx / sites-enabled, например:
$ sudo ln -s /etc/nginx/sites-available/survey /etc/nginx/sites-enabled
Чтобы разрешить трафик через порт HTTP и привязать к Nginx, я ufw
а
также закрою ранее открытый порт 5000.
$ sudo ufw delete allow 5000
$ sudo ufw allow 'Nginx Full'
Следуя этой команде, мне нужно будет перезапустить службу Nginx, чтобы обновления вступили в силу.
$ sudo systemctl restart nginx
Теперь я могу снова зайти в свой браузер и посетить
http://123.454.67.89
и мне будет представлено приложение для опроса,
которое я показал в предыдущих статьях.
Заключение
Что ж, это заключительный пост в этой серии руководств, состоящих из нескольких частей, о том, как использовать Flask и Vue.js для создания приложения SPA с поддержкой REST API. Я попытался охватить большинство важных тем, которые являются общими для многих случаев использования веб-приложений, предполагая очень мало предварительных знаний об используемых технологиях Flask и Vue.js.
Я благодарю вас за то, что вы следите за этой серией, и, пожалуйста, не стесняйтесь комментировать или критиковать ниже.