Рубрики
Без рубрики

Одностраничные приложения с Vue.js и Колба: Развертывание

Автор оригинала: Adam McQuistan.

Развертывание на виртуальном частном сервере

Добро пожаловать в седьмую и последнюю часть этой многосоставной серии учебников по полнотекстовой веб-разработке с использованием Vue.js и Фляжка. В этом посте я продемонстрирую, как развертывать приложение, построенное на протяжении всей этой серии.

Код для этого поста можно найти на моем аккаунте GitHub под веткой Седьмой пост .

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

  1. Настройка и знакомство с VueJS
  2. Навигация по маршрутизатору Vue
  3. Государственное управление с помощью Vuex
  4. RESTful API с колбой
  5. Интеграция AJAX с REST API
  6. Аутентификация JWT
  7. Развертывание на виртуальном частном сервере (вы находитесь здесь)

Обзор технологий

Этот учебник будет охватывать несколько технологий, необходимых для развертывания распределенного многоуровневого Flask REST API и Vue.js СПА-приложение. Ниже я перечислил технологии и их использование:

  • Ubuntu LTS 16.04: хост-сервер для запуска различных приложений и серверов
  • uWSGI: Web server Gateway Interface (WSGI) контейнерный сервер для выполнения приложений Python (в данном случае Flask)
  • Nginx: высокоэффективный неблокирующий HTTP-веб-сервер, способный к обратному проксированию к uWSGI
  • Node.js/NPM: Javascript-среда для построения Vue.js СПА-приложение

Подготовка кода к развертыванию

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

Например, в api/index.js из survey-spa Vue.js приложение Я жестко закодировал переменную с именем API_URL , чтобы указать на dev-сервер 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 – это переменная окружения, которую я добавлю в файл user .bash_profile сервера Ubuntu и установлю его равным IP-адресу сервера.

А потом туда api/index.js Я изменяю строку const и устанавливаю ее равной process.env.API_URL .

Далее, в приложении Flask мне нужно добавить новый модуль под названием wsgi.py служить точкой входа в API REST Flask. В wsgi.py модуль выглядит довольно похожим на appserver.py модуль, за исключением этого, не имеет никаких вызовов метода run(...) объекта app. Это происходит потому, что объект app будет служить вызываемым для контейнерного сервера 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 и установлю зависимости frontend, а также создам производственное приложение.

$ cd flask-vuejs-survey/frontend/survey-spa
$ npm install
$ npm run build

Это создает новый каталог под названием “dist”, который будет содержать index.html страница и каталог под названием “static”, который содержит все скомпилированные файлы CSS и JavaScript. Это то, что у меня будет Nginx-сервер, чтобы составить интерфейсное приложение SPA.

Далее я создам виртуальную среду в каталоге/home/survey для изолированного интерпретатора Python3 для запуска приложения Python. После установки я активирую его и перемещаюсь в каталог backend project для установки его пакетов зависимостей, указанных в 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 dev, чтобы убедиться, что все работает так, как ожидалось. Прежде чем сделать это, мне нужно сказать службе ufw разрешить трафик на порт 5000.

(venv) $ sudo ufw allow 5000
(venv) $ python appserver.py

В браузере я теперь могу перейти к http://123.45.67.89:5000/api/surveys/ и я должен увидеть простой JSON-ответ [] , потому что в этой базе данных еще нет опросов, но это указывает на то, что был сделан успешный запрос. Кроме того, в терминале, подключенном к серверу, должно быть записано сообщение для запроса GET , выданного моим браузером.

Я нажимаю Ctrl+C в терминале, чтобы убить сервер разработки Flask, и перехожу к настройке uwsgi для управления выполнением моего API REST Flask. Если вам интересно, откуда взялся uwsgi, то он указан как требование в requirements.txt файл, с которым я установил pip ранее.

Настройка контейнерного сервера uWSGI

Подобно тому, что я только что сделал с сервером Flask dev, теперь я проверю, что сервер uWSGI может обслуживать приложение следующим образом.

(venv) $ uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

Опять же, переход в мой браузер и обновление того же запроса, который я сделал ранее, должны вернуть пустой ответ массива JSON. Удовлетворившись своим прогрессом, я снова могу нажать Ctrl+C в терминале и двигаться дальше.

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

В бэкэнд – каталоге я создаю файл survey api.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 мне нужно создать файл с именем survey api.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

Теперь я могу запустить службу, проверить ее состояние и убедиться, что внутренний каталог теперь содержит survey api.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, созданный при сборке Vue.js переднее СПА-приложение до этого.

С помощью этого конфигурационного файла мне нужно сообщить Nginx, что это доступный сайт, создав символическую ссылку на каталог/etc/nginx/sites-enabled, например:

$ sudo ln -s /etc/nginx/sites-available/survey /etc/nginx/sites-enabled 

Чтобы разрешить трафик через HTTP-порт и привязаться к Nginx, я выпущу следующее обновление для ofw , а также закрою ранее открытый 5000-порт.

$ sudo ufw delete allow 5000
$ sudo ufw allow 'Nginx Full'

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

$ sudo systemctl restart nginx

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

Вывод

Ну что ж это заключительный пост к этой многосоставной серии учебников о том как использовать колбу и Vue.js для создания СПА-приложения с поддержкой REST API. Я попытался охватить большинство важных тем, которые являются общими для многих случаев использования веб-приложений, предполагая очень мало предварительных знаний о колбе и Vue.js используемые технологии.

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