Implementaci贸n en un servidor privado virtual
Contenido
Bienvenido a la s茅ptima y 煤ltima entrega de esta serie de tutoriales de varias partes sobre desarrollo web full-stack usando Vue.js y Flask. En esta publicaci贸n, demostrar茅 c贸mo implementar la aplicaci贸n construida a lo largo de esta serie.
El c贸digo para esta publicaci贸n se puede encontrar en mi cuenta de GitHub en la rama S茅ptima Publicaci贸n.
Contenido de la serie
- Seup y familiarizaci贸n con VueJS
- Navegando por el enrutador Vue
- Gesti贸n de estado con Vuex
- API RESTful con Flask
- Integraci贸n AJAX con API REST
- Autenticaci贸n JWT
- Implementaci贸n en un servidor privado virtual (usted est谩 aqu铆)
Resumen de las tecnolog铆as
Este tutorial cubrir谩 varias tecnolog铆as necesarias para implementar una API REST de Flask de varios niveles distribuida y una aplicaci贸n Vue.js SPA. A continuaci贸n, he enumerado las tecnolog铆as y sus usos:
- Ubuntu LTS 16.04: servidor host para ejecutar varias aplicaciones y servidores
- uWSGI: servidor contenedor Webserver Gateway Interface (WSGI) para ejecutar aplicaciones Python (Flask en este caso)
- Nginx: servidor web HTTP sin bloqueo de alto rendimiento capaz de realizar proxy inverso a uWSGI
- Node.js / NPM: entorno Javascript para compilar la aplicaci贸n Vue.js SPA
Preparar el c贸digo para la implementaci贸n
Hay un par de cambios que deben realizarse en el c贸digo para que sea m谩s f谩cil de mantener una vez que la aplicaci贸n se haya implementado en mi entorno de producci贸n.
Por ejemplo, en api / index.js del survey-spa
Aplicaci贸n Vue.js He codificado una variable llamada API_URL
para apuntar al servidor de desarrollo http://127.0.0.1:5000/api
. Al hacer esto, tendr茅 que recordar cambiar esto a la direcci贸n IP del servidor de producci贸n cada vez que necesite implementar.
La experiencia me ha ense帽ado que siempre habr谩 cambios en la aplicaci贸n que requieran futuras implementaciones donde es probable que me olvide de actualizar esta direcci贸n IP. Un mejor enfoque es eliminar el riesgo de que me olvide de actualizar esto y, en su lugar, utilice configuraciones en el proceso de compilaci贸n para manejar esto por m铆, lo que resulta en menos de lo que tengo que recordar (es decir, se necesitan menos pasos) durante la implementaci贸n. Esto reduce significativamente el riesgo de una implementaci贸n fallida en futuras actualizaciones.
Lo logro movi茅ndome al directorio survey-spa / config y modificando los archivos dev.env.js y prod.env.js definiendo una variable llamada API_URL
a los que se les asigna un valor de http://localhost:5000/api
para dev y http://${process.env.BASE_URL}/api
para prod como se muestra a continuaci贸n:
// 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`)
}
Nota: el valor de process.env.BASE_URL
es una variable de entorno que agregar茅 al usuario del servidor de Ubuntu .bash_profile y la establecer茅 igual a la direcci贸n IP del servidor.
Luego, en api / index.js modifico la l铆nea const API_URL = 'http://127.0.0.1:5000/api'
y ponerlo igual a process.env.API_URL
.
A continuaci贸n, en la aplicaci贸n Flask, necesito agregar un nuevo m贸dulo llamado wsgi.py para que sirva como punto de entrada a la API REST de Flask. El m贸dulo wsgi.py se parece bastante al m贸dulo appserver.py, excepto que no tiene ninguna llamada al run(...)
m茅todo del objeto de la aplicaci贸n. Esto se debe a que el objeto de la aplicaci贸n servir谩 como un invocable para que el servidor de contenedores uwsgi se ejecute utilizando su protocolo binario r谩pido en lugar del servidor de desarrollo normal que se crea cuando app.run(...)
se llama.
# backend/wsgi.py
from surveyapi.application import create_app
app = create_app()
Con esto terminado, puedo enviar mis cambios al control de versiones y saltar a mi servidor de producci贸n para desplegar el proyecto y configurar los programas que usar茅 para ejecutar la aplicaci贸n en el servidor de producci贸n.
Preparando el servidor Ubuntu
A continuaci贸n, entrar茅 en mi servidor privado virtual Ubuntu de producci贸n, que podr铆a estar alojado en uno de los muchos servicios en la nube, como AWS, DigitalOcean, Linode, etc., y comenzar茅 a instalar todas las ventajas que enumer茅 en la Descripci贸n general de las tecnolog铆as. secci贸n.
$ apt-get update
$ apt-get install python3-pip python3-dev python3-venv nginx nodejs npm
Con esas instalaciones fuera del camino, ahora puedo crear un usuario llamado “encuesta” para ejecutar la aplicaci贸n y albergar el c贸digo.
$ adduser survey
$ usermod -aG sudo survey
$ su survey
$ cd
Ahora deber铆a estar en el directorio de inicio del usuario de “encuesta” en / home / survey.
Con la encuesta creada por el usuario, puedo actualizar el archivo .bash_profile para que contenga la direcci贸n IP de mi servidor de producci贸n agregando esta l铆nea al final del archivo. Tenga en cuenta que 123.45.67.89 representa una direcci贸n IP falsa de mi servidor. Reempl谩celo con su verdadera direcci贸n IP si lo est谩 siguiendo.
export BASE_URL=123.45.67.89
A continuaci贸n, quiero decirle al firewall (ufw) que OpenSSH es aceptable y habil铆telo.
$ sudo ufw allow OpenSSH
$ sudo ufw enable
Una vez hecho esto, ahora clonar茅 el repositorio en el servidor para poder construirlo e implementarlo.
$ git clone https://github.com/amcquistan/flask-vuejs-survey.git
Ahora ingresar茅 en flask-vuejs-survey / frontend / survey-spa e instalar茅 las dependencias de frontend y construir茅 la aplicaci贸n de producci贸n.
$ cd flask-vuejs-survey/frontend/survey-spa
$ npm install
$ npm run build
Esto crea un nuevo directorio llamado “dist”, que contendr谩 una p谩gina index.html y un directorio llamado “est谩tico” que contiene todos los archivos CSS y JavaScript compilados. Estos son los que tendr茅 en el servidor Nginx para constituir la aplicaci贸n de front-end del SPA.
A continuaci贸n, crear茅 un entorno virtual en el directorio / home / survey para que un int茅rprete de Python3 aislado ejecute la aplicaci贸n Python. Una vez instalado, lo activo y me muevo al directorio del proyecto backend para instalar sus paquetes de dependencia especificados en el archivo requirements.txt.
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ cd flask-vuejs-survey/backend
(venv) $ pip install -r requirements.txt
Ahora puedo inicializar la base de datos sqlite y ejecutar las migraciones para crear las diversas tablas de base de datos requeridas por la API REST.
(venv) $ python manage.py db upgrade
En este punto, me gustar铆a encender el servidor de desarrollo Flask para asegurarme de que todo funciona como se esperaba. Antes de hacerlo, necesito decirle al ufw
servicio para permitir el tr谩fico en el puerto 5000.
(venv) $ sudo ufw allow 5000
(venv) $ python appserver.py
En un navegador ahora puedo ir a http://123.45.67.89:5000/api/surveys/
y deber铆a ver una simple respuesta JSON de []
porque a煤n no hay encuestas en esta base de datos, pero esto indica que se realiz贸 una solicitud con 茅xito. Adem谩s, en el terminal conectado al servidor deber铆a haber un mensaje registrado para la solicitud GET emitida desde mi navegador.
Tecleo Ctrl + C en la terminal para matar el servidor de desarrollo de Flask y paso a configurar uwsgi para controlar la ejecuci贸n de mi API REST de Flask. Si se est谩 preguntando de d贸nde vino uwsgi, se especifica como un requisito en el archivo requirements.txt que instal茅 anteriormente.
Configuraci贸n del servidor de contenedores uWSGI
De manera similar a lo que acabo de hacer con el servidor de desarrollo Flask, ahora probar茅 que el servidor uWSGI puede servir la aplicaci贸n de la siguiente manera.
(venv) $ uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
Nuevamente, ir a mi navegador y actualizar la misma solicitud que hice anteriormente deber铆a devolver una respuesta de matriz JSON vac铆a. Una vez satisfecho con mi progreso, puedo volver a presionar Ctrl + C en la terminal y seguir adelante.
Hay dos pasos m谩s que me gustar铆a seguir para completar la configuraci贸n del servidor de contenedores uWSGI. Un paso es crear un archivo de configuraci贸n que leer谩 uWSGI en el que reemplazar谩 muchos de los indicadores y argumentos de la l铆nea de comando que utilic茅 anteriormente. El segundo paso es crear un archivo de servicio systemd para administrar el servidor contenedor uWSGI como un servicio como muchos de los otros que ya se ejecutan en el servidor Ubuntu.
En el directorio de backend, hago un archivo llamado surveyyapi.ini y lo lleno con lo siguiente:
[uwsgi]
module = wsgi:app
master = true
processes = 4
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
Este archivo de configuraci贸n le permite a uWSGI saber que el invocable es el objeto de la aplicaci贸n dentro del m贸dulo wsgi.py. Tambi茅n le dice que genere y use cuatro procesos para manejar solicitudes de aplicaciones comunicadas a trav茅s de un archivo de socket llamado surveyyapi.sock que tiene un permiso lo suficientemente flexible como para permitir que el servidor web Nginx lea y escriba desde 茅l. los vacuum
y die-on-term
Los ajustes son para asegurar una limpieza adecuada.
Para el archivo de servicio systemd, necesito crear un archivo llamado surveyapi.service
en el directorio / etc / systemd / system y agregue algunos descriptores m谩s los comandos de acceso, escritura y ejecuci贸n de la siguiente manera:
(venv) $ sudo nano /etc/systemd/system/surveyapi.service
Luego, compl茅telo con lo siguiente:
[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
Ahora puedo iniciar el servicio y verificar su estado y asegurarme de que el directorio de backend ahora contenga surveyyapi.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
隆Excelente! Lo 煤ltimo que debo hacer es habilitar el inicio autom谩tico cada vez que se inicia el sistema, asegur谩ndome de que la aplicaci贸n est茅 siempre activa.
(venv) $ sudo systemctl enable surveyapi
Configuraci贸n de Nginx
Utilizar茅 Nginx para servir contenido est谩tico como HTML, CSS y JavaScript, as铆 como para revertir las llamadas API REST del proxy a la aplicaci贸n Flask / uWSGI. Para configurar nginx para lograr estas cosas, necesitar茅 crear un archivo de configuraci贸n que defina c贸mo administrar estas diversas solicitudes.
En / etc / nginx / sites-available, crear茅 un archivo llamado encuesta que contendr谩 lo siguiente:
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;
}
}
Este archivo crea una nueva configuraci贸n de bloque de servidor que dice que escuche la direcci贸n IP 123.45.67.89 en el puerto HTTP est谩ndar de 80. Luego dice que busque cualquier ruta URI que comience con / api y un proxy inverso al servidor Flask / uWSGI REST API utilizando el archivo de socket definido previamente. Por 煤ltimo, la configuraci贸n dice que capture todo lo dem谩s en / y sirva el archivo index.html en el directorio dist creado cuando constru铆 la aplicaci贸n SPA de front-end Vue.js antes.
Con este archivo de configuraci贸n creado, necesito informarle a Nginx que es un sitio disponible creando un enlace simb贸lico al directorio / etc / nginx / sites-enabled como sigue:
$ sudo ln -s /etc/nginx/sites-available/survey /etc/nginx/sites-enabled
Para permitir el tr谩fico a trav茅s del puerto HTTP y enlazar con Nginx, emitir茅 la siguiente actualizaci贸n para ufw
as铆 como cerrar el puerto 5000 previamente abierto.
$ sudo ufw delete allow 5000
$ sudo ufw allow 'Nginx Full'
Siguiendo este comando, tendr茅 que reiniciar el servicio Nginx para que las actualizaciones surtan efecto.
$ sudo systemctl restart nginx
Ahora puedo volver a mi navegador y visitar http://123.454.67.89
y se me presenta la aplicaci贸n de encuesta que he mostrado en art铆culos anteriores.
Conclusi贸n
Bueno, esta es la publicaci贸n final de esta serie de tutoriales de varias partes sobre c贸mo utilizar Flask y Vue.js para construir una aplicaci贸n SPA habilitada para REST API. He intentado cubrir la mayor铆a de los temas importantes que son comunes a muchos casos de uso de aplicaciones web, asumiendo muy poco conocimiento previo de las tecnolog铆as Flask y Vue.js utilizadas.
Les agradezco por seguir esta serie y, por favor, no tengan verg眉enza de comentar o criticar a continuaci贸n.