Jednostránkové aplikace s Vue.js a Flask:Deployment

Nasazení na virtuální privátní server

Vítejte u sedmého a posledního dílu této vícedílné série výukových programů o komplexním vývoji webu pomocí Vue.js a Flask. V tomto příspěvku ukážu, jak nasadit aplikaci postavenou v této sérii.

Kód pro tento příspěvek najdete na mém účtu GitHub pod pobočkou SeventhPost.

Obsah seriálu

  1. Nastavení a seznámení s VueJS
  2. Navigace Vue Router
  3. Správa státu se společností Vuex
  4. RESTful API s Flask
  5. Integrace AJAX s REST API
  6. Ověření JWT
  7. Nasazení na virtuální privátní server (jste zde)

Přehled technologií

Tento tutoriál bude pokrývat několik technologií nezbytných k nasazení distribuovaného vícevrstvého Flask REST API a aplikace Vue.js SPA. Níže jsem uvedl seznam technologií a jejich použití:

  • Ubuntu LTS 16.04:hostitelský server pro spouštění různých aplikací a serverů
  • uWSGI:Kontejnerový server Webserver Gateway Interface (WSGI) pro spouštění aplikací Python (v tomto případě Flask)
  • Nginx:Vysoce výkonný neblokující webový server HTTP schopný reverzní proxy na uWSGI
  • Node.js / NPM:Prostředí Javascript pro vytváření aplikace Vue.js SPA

Příprava kódu k nasazení

Existuje několik změn, které je třeba provést v kódu, aby byl po nasazení aplikace do mého produkčního prostředí lépe udržovatelný.

Například v api/index.js z survey-spa Aplikace Vue.js Mám pevně zakódovanou proměnnou nazvanou API_URL přejděte na dev server http://127.0.0.1:5000/api . Abych to udělal, budu si muset pamatovat, že to musím změnit na IP adresu produkčního serveru pokaždé, když potřebuji nasazení.

Zkušenost mě naučila, že v aplikaci vždy dojde ke změnám vyžadujícím budoucí nasazení, kde pravděpodobně zapomenu aktualizovat tuto IP adresu. Lepším přístupem je odstranit riziko, že zapomenu toto aktualizovat a místo toho použiji konfigurace v procesu sestavování, které to za mě vyřídí, což má za následek méně toho, co si musím pamatovat (tj. méně potřebných kroků) během nasazení. To výrazně snižuje riziko neúspěšného nasazení při budoucích aktualizacích.

Dosahuji toho přesunutím do adresáře survey-spa/config a úpravou souborů dev.env.js a prod.env.js definováním proměnné nazvané API_URL kterým je přiřazena hodnota http://localhost:5000/api pro vývojáře a http://${process.env.BASE_URL}/api pro produkt, jak je uvedeno níže:

// 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`)
}

Poznámka :hodnota process.env.BASE_URL je proměnná prostředí, kterou přidám k uživateli serveru Ubuntu .bash_profile a nastavím ji na stejnou IP adresu serveru.

Poté v api/index.js upravím řádek const API_URL = 'http://127.0.0.1:5000/api' a nastavte ji na process.env.API_URL .

Dále v aplikaci Flask musím přidat nový modul s názvem wsgi.py, který bude sloužit jako vstupní bod do Flask REST API. Modul wsgi.py vypadá docela podobně jako modul appserver.py až na to, že nemá žádná volání run(...) metoda objektu aplikace. Je to proto, že objekt aplikace bude sloužit jako callable pro kontejnerový server uwsgi, který se má spustit pomocí jeho rychlého binárního protokolu, nikoli běžného vývojového serveru, který se vytvoří, když app.run(...) se nazývá.

# backend/wsgi.py

from surveyapi.application import create_app
app = create_app()

Když je toto hotovo, mohu vložit své změny do správy verzí a naskočit na svůj produkční server, stáhnout projekt a nastavit programy, které budu používat ke spuštění aplikace na produkčním serveru.

Příprava serveru Ubuntu

Dále se dostanu na svůj produkční virtuální soukromý server Ubuntu, který by mohl být hostován jednou z mnoha cloudových služeb, jako je AWS, DigitalOcean, Linode, atd... a začnu instalovat všechny vychytávky, které jsem uvedl v Přehledu technologií sekce.

$ apt-get update
$ apt-get install python3-pip python3-dev python3-venv nginx nodejs npm

Díky těmto instalacím z cesty mohu nyní vytvořit uživatele s názvem „průzkum“, který spustí aplikaci pod kódem a uloží jej.

$ adduser survey
$ usermod -aG sudo survey
$ su survey
$ cd

Nyní bych měl být v domovském adresáři uživatele „průzkumu“ na adrese /home/survey.

S vytvořeným uživatelem průzkumu mohu aktualizovat soubor .bash_profile tak, aby obsahoval IP adresu mého produkčního serveru přidáním tohoto řádku na konec souboru. Všimněte si, že 123.45.67.89 představuje falešnou IP adresu mého serveru. Pokud ji sledujete, nahraďte ji svou skutečnou IP adresou.

export BASE_URL=123.45.67.89

Dále chci firewallu (ufw) sdělit, že OpenSSH je přijatelné a povolit jej.

$ sudo ufw allow OpenSSH
$ sudo ufw enable

S tímto hotovým nyní naklonuji repo na server, abych jej mohl sestavit a nasadit.

$ git clone https://github.com/amcquistan/flask-vuejs-survey.git

Nyní udělám cd do flask-vuejs-survey/frontend/survey-spa a nainstaluji frontendové závislosti a také vytvořím produkční aplikaci.

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

Tím se vytvoří nový adresář s názvem „dist“, který bude obsahovat stránku index.html a adresář s názvem „static“, který obsahuje všechny zkompilované soubory CSS a JavaScript. To je to, co budu mít server Nginx, aby vytvořil front-endovou aplikaci SPA.

Dále vytvořím virtuální prostředí v adresáři /home/survey pro izolovaný interpret Python3 pro spuštění aplikace Python. Po instalaci jej aktivuji a přesunu se do adresáře backendového projektu, kde nainstaluji jeho balíčky závislostí specifikované v souboru requirements.txt.

Zdarma e-kniha:Git Essentials

Prohlédněte si našeho praktického průvodce učením Git s osvědčenými postupy, průmyslově uznávanými standardy a přiloženým cheat sheetem. Přestaňte používat příkazy Google Git a skutečně se naučte to!

$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ cd flask-vuejs-survey/backend
(venv) $ pip install -r requirements.txt

Nyní mohu inicializovat databázi sqlite a spustit migrace pro vytvoření různých databázových tabulek vyžadovaných REST API.

(venv) $ python manage.py db upgrade

V tuto chvíli bych chtěl spustit Flask dev server, abych se ujistil, že vše funguje podle očekávání. Než tak učiním, musím sdělit ufw služba umožňující provoz na portu 5000.

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

V prohlížeči nyní mohu přejít na http://123.45.67.89:5000/api/surveys/ a měl bych vidět jednoduchou odpověď JSON [] protože v této databázi zatím nejsou žádné průzkumy, ale to znamená, že byla podána úspěšná žádost. Kromě toho by v terminálu připojeném k serveru měla být protokolovaná zpráva pro GET požadavek vydán z mého prohlížeče.

Zadám Ctrl+C v terminálu, abych zabil dev server Flask a přešel ke konfiguraci uwsgi pro řízení provádění mého Flask REST API. Pokud vás zajímá, odkud se uwsgi vzalo, je to specifikováno jako požadavek v souboru requirements.txt, který jsem nainstaloval dříve.

Nastavení kontejnerového serveru uWSGI

Podobně jako to, co jsem právě udělal s dev serverem Flask, nyní otestuji, že server uWSGI může aplikaci obsluhovat následovně.

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

Opět platí, že přechod do mého prohlížeče a obnovení stejného požadavku, který jsem provedl dříve, by mělo vrátit prázdnou odpověď pole JSON. Jakmile jsem se svým postupem spokojen, mohu znovu stisknout Ctrl+C do terminálu a pokračovat.

K dokončení konfigurace kontejnerového serveru uWSGI bych chtěl udělat ještě dva kroky. Jedním krokem je vytvoření konfiguračního souboru, který bude uWSGI číst a který nahradí mnoho z těch příznaků a argumentů příkazového řádku, které jsem použil výše. Druhým krokem je vytvoření souboru služby systemd pro správu kontejnerového serveru uWSGI jako služby, jako je mnoho dalších, které již běží na serveru Ubuntu.

V backendovém adresáři vytvořím soubor s názvem surveyapi.ini a naplním ho následujícím:

[uwsgi]
module = wsgi:app

master = true
processes = 4

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

Tento konfigurační soubor dává uWSGI vědět, že callable je objekt aplikace uvnitř modulu wsgi.py. Také mu říká, aby se vytvořil a použil čtyři procesy ke zpracování požadavků aplikací komunikovaných přes soubor soketu s názvem surveyapi.sock, který má dostatečně volné oprávnění, aby z něj mohl webový server Nginx číst a zapisovat. vacuum a die-on-term nastavení má zajistit řádné čištění.

Pro soubor služby systemd musím vytvořit soubor s názvem surveyapi.service v adresáři /etc/systemd/system a přidejte některé deskriptory plus příkazy pro přístup, zápis a provádění, jako je tento:

(venv) $ sudo nano /etc/systemd/system/surveyapi.service

Poté jej vyplňte takto:

[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

Nyní mohu spustit službu a zkontrolovat její stav a ujistit se, že backendový adresář nyní obsahuje 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

Vynikající! Poslední věc, kterou bych měl udělat, je povolit automatické spouštění pokaždé, když se systém spustí, aby bylo zajištěno, že aplikace bude vždy spuštěna.

(venv) $ sudo systemctl enable surveyapi

Nastavení Nginx

Využiji Nginx k poskytování statického obsahu, jako je HTML, CSS a JavaScript, a také k obrácení volání proxy REST API do aplikace Flask / uWSGI. Abych nginx nastavil tak, aby tyto věci splnil, budu muset vytvořit konfigurační soubor, který definuje, jak spravovat tyto různé požadavky.

Přes v /etc/nginx/sites-available vytvořím soubor nazvaný průzkum, který bude obsahovat následující:

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;
  }
}

Tento soubor vytvoří novou konfiguraci bloku serveru, která říká, že má naslouchat IP adrese 123.45.67.89 na standardním HTTP portu 80. Pak říká, že hledejte všechny cesty URI začínající na /api a reverzní proxy, které k serveru Flask / uWSGI REST API pomocí dříve definovaného soketového souboru. Nakonec konfigurace říká, že je třeba zachytit vše ostatní pod / a naservírovat soubor index.html v adresáři dist vytvořeném, když jsem předtím vytvořil front-end aplikaci Vue.js.

S tímto vytvořeným konfiguračním souborem musím dát Nginx vědět, že se jedná o dostupný web vytvořením symbolického odkazu na adresář /etc/nginx/sites-enabled takto:

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

Abych povolil provoz přes HTTP port a navázal se na Nginx, vydám následující aktualizaci na ufw a také zavřete dříve otevřený port 5000.

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

Po tomto příkazu budu muset restartovat službu Nginx, aby se aktualizace projevily.

$ sudo systemctl restart nginx

Nyní mohu znovu přejít do prohlížeče a navštívit http://123.454.67.89 a zobrazí se mi aplikace průzkumu, kterou jsem ukázal v předchozích článcích.

Závěr

Toto je závěrečný příspěvek této vícedílné série tutoriálů o tom, jak využít Flask a Vue.js k vytvoření SPA aplikace s podporou REST API. Pokusil jsem se pokrýt většinu důležitých témat, která jsou společná pro mnoho případů použití webových aplikací, za předpokladu velmi malých předchozích znalostí používaných technologií Flask a Vue.js.

Děkuji vám za sledování této série a prosím, nestyďte se níže komentovat nebo kritizovat.