Capítulo 4. Google App Engine
Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com
Google App Engine es una solución informática sin servidor que te permite ejecutar tus aplicaciones sin tener que gestionar la infraestructura subyacente. App Engine es compatible con diversos lenguajes de programación, como Node.js, Java, Ruby, C#, Go, Python y PHP; incluso puedes utilizar un lenguaje no compatible utilizando contenedores. App Engine tiene dos ediciones: Estándar y Flexible. Flexible te permite incorporar cualquier biblioteca y framework a App Engine.
App Engine te proporciona funciones de implementación preparadas para la empresa, como versionado de aplicaciones, división del tráfico, seguridad, monitoreo y depuración. Con App Engine, sólo tienes que centrarte en tu código; Google Cloud gestiona la infraestructura subyacente. En este capítulo, aprenderás a implementar tu aplicación con una canalización CI/CD, a protegerla, a asignar un dominio personalizado, a utilizar las API de ML y a depurar tu aplicación.
Todos los ejemplos de código de este capítulo están en el repositorio GitHub de este libro. Puedes seguirlos y copiar el código de cada receta yendo a la carpeta con el número de esa receta.
Tendrás que asegurarte de que cumples los requisitos previos antes de ejecutar las recetas:
Regístrate para obtener una cuenta de Google Cloud, como se describe en el Capítulo 1.
Crea un proyecto de Google Cloud, como se describe en el Capítulo 1.
Instala y configura gcloud, como se describe en el Capítulo 1.
Habilitadas las APIs Cloud Functions y Cloud Build.
gcloud services enable cloudbuild.googleapis.com gcloud services enable \ containerregistry.googleapis.com
4.1 Implementación de un Hola Mundo en App Engine (Estándar)
Solución
Utiliza la línea de comandos de Google Cloud y tu editor favorito para crear una sencilla aplicación Express.js que se ejecute en App Engine.
En tu estación de trabajo local, crea una carpeta temporal para guardar los archivos que necesitarás para crear la aplicación Hola Mundo.
En tu IDE favorito, crea un archivo app.js en la raíz del directorio que creaste en el paso 1 y copia el siguiente código en el archivo:
'use strict'; const express = require('express'); const app = express(); app.get('/', (req, res) => { res.status(200).send('Hello, world!').end(); }); const PORT = process.env.PORT || 8080; app.listen(PORT, () => { console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); module.exports = app;
Ahora crea un archivo app.yam l en la raíz del mismo directorio y copia el siguiente código en el archivo. El archivo app. yaml define la configuración de tu aplicación, incluido el tiempo de ejecución de tu código.
runtime: nodejs14
Ahora crea un archivo package.json en la raíz del mismo directorio y copia el siguiente código en el archivo:
{ "name": "appengine-hello-world", "engines": { "node": ">=14.0.0" }, "scripts": { "start": "node app.js" }, "dependencies": { "express": "^4.17.1" } }
En tu terminal, ejecuta el siguiente comando en el directorio raíz que creaste en el paso 1:
npm install
Para implementar la aplicación en App Engine Standard, ejecuta el siguiente comando:
gcloud app deploy
Para ver tu aplicación implementada, ejecuta el siguiente comando:
gcloud app browse
Esto abrirá la aplicación en tu navegador predeterminado.
Debate
Has implementado con éxito tu primera aplicación App Engine utilizando Node.js. Se trata de una sencilla aplicación Hola Mundo, pero demuestra algunos de los conceptos básicos de la implementación de los servicios de App Engine. Para revisar las diferencias entre App Engine Standard y Flexible, salta a la Tabla 4-1 que enumera las diferencias .
4.2 Implementación de un Hola Mundo en App Engine (Flexible)
Solución
App Engine Flexible admite la ejecución de un contenedor Docker que puede incluir tiempos de ejecución personalizados u otro código fuente escrito en un lenguaje de programación diferente. Dado que App Engine Flexible admite la ejecución de contenedores Docker, utilizarás la versión Flexible de App Engine para implementar un sencillo Hola Mundo.
En tu estación de trabajo local, crea una carpeta temporal para guardar los archivos que necesitarás para crear la aplicación Hola Mundo.
En tu IDE favorito, crea un archivo Dockerfile en la raíz del directorio que creaste en el paso 1 y copia el siguiente código en el archivo:
FROM nginx COPY nginx.conf /etc/nginx/nginx.conf RUN mkdir -p /var/log/app_engine RUN mkdir -p /usr/share/nginx/www/_ah && \ echo "healthy" > /usr/share/nginx/www/_ah/health ADD www/ /usr/share/nginx/www/ RUN chmod -R a+r /usr/share/nginx/www
Nota
El comando FROM construye una imagen base, utilizando la imagen Docker oficial de NGINX.
Crea un nuevo archivo llamado app.yaml en la raíz de tu directorio temporal y escribe en él el siguiente código:
runtime: custom env: flex
Ahora crea un nuevo archivo llamado nginx.conf, también en la raíz del directorio temporal que has creado, y escribe en él el siguiente código:
events { worker_connections 768; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/app_engine/app.log; error_log /var/log/app_engine/app.log; gzip on; gzip_disable "msie6"; server { listen 8080; root /usr/share/nginx/www; index index.html index.htm; } }
Crea una nueva carpeta llamada www en la raíz de tu directorio temporal.
Dentro de la carpeta www, crea un nuevo archivo llamado index.html y copia en él el siguiente código:
<!doctype html> <html> <head> <title>Hello World!</title> </head> <body> <h1>Welcome to nginx!</h1> <p>Brought to you by Google App Engine.</p> </body> </html>
Ejecuta el siguiente comando para implementar tu aplicación en App Engine:
gcloud app deploy
Para ver tu aplicación implementada, ejecuta el siguiente comando:
gcloud app browse
Esto abrirá la aplicación en tu navegador predeterminado.
Debate
Has implementado con éxito una aplicación web estática que se ejecuta en un servidor web NGINX como tiempo de ejecución personalizado en App Engine Flexible. App Engine Flexible es una opción perfecta para aplicaciones que:
Necesitas un tiempo de ejecución personalizado.
Depender de frameworks que no son compatibles con App Engine Standard.
La Tabla 4-1 resume las diferencias entre App Engine Standard y Flexible a alto nivel.
Función | Entorno estándar | Entorno flexible |
---|---|---|
Tiempo de inicio de la instancia | Segundos | Actas |
Depuración SSH | No | Sí |
Escalado | Manual, básico, automático | Manual, automático |
Escala a cero | Sí | No, mínimo 1 instancia |
Modificar el tiempo de ejecución | No | Sí (a través de Dockerfile) |
Tiempo de Implementación | Segundos | Actas |
WebSockets | No | Sí |
Admite la instalación de binarios de terceros | Sí | Sí |
4.3 Proteger tu aplicación con un proxy consciente de la identidad
Solución
Utiliza el proxy Google Cloud Identity-Aware (IAP) para restringir el acceso sólo a un conjunto de usuarios predefinidos. IAP proporciona un único punto de control para gestionar el acceso de los usuarios a tus aplicaciones. Utilizaremos la aplicación Hola Mundo Nube creada en la Receta 4.1 para protegerla con IAP.
Ve a la página IAP de la Consola de Google Cloud, como se muestra en la Figura 4-1.
Nota
Si no has configurado tu pantalla de consentimiento OAuth, tendrás que configurarla antes de continuar.
Selecciona el recurso que quieres asegurar marcando la casilla a su izquierda.
En el panel de la derecha, haz clic en Añadir miembro.
Añade las direcciones de correo electrónico de los grupos o individuos a los que quieras conceder acceso a tu aplicación App Engine. IAP Identity and Access Management (IAM) admite las siguientes cuentas:
Cuenta de Google
Grupo Google
Cuenta de servicio
Dominio G Suite
Cuando hayas añadido todas las cuentas a las que quieras dar acceso a tu aplicación, haz clic en Añadir.
En la página IAP, en Recursos HTTPS, busca la app de App Engine a la que quieras restringir el acceso y activa/desactiva el interruptor en la columna IAP; consulta la Figura 4-2.
Accede a la URL de tu aplicación App Engine. Se te pedirá que inicies sesión. Si no se te pide, intenta iniciar sesión con una ventana de incógnito.
Si has autorizado una cuenta de usuario y éste inicia sesión con la cuenta asociada, tendrá acceso completo a tu aplicación que se ejecuta en App Engine.
Si no has concedido acceso a una cuenta e intentan acceder a tu aplicación, recibirán un mensaje No tienes acceso.
Debate
Con el Proxy Identity-Aware de Google Cloud, puedes restringir el acceso a tu aplicación que se ejecuta en App Engine, impidiendo el acceso no autorizado a tus recursos. El Proxy Identity-Aware también admite identidades externas como Google, Microsoft, Email/Password y otras, que proporcionan un sólido conjunto de opciones de inicio de sesión para que tus usuarios accedan a tu aplicación(Figura 4-3).
4.4 Asignación de dominios personalizados con App Engine
Solución
Google Cloud ofrece la posibilidad de asignar dominios personalizados. También puede emitir un certificado gestionado para SSL para conexiones HTTPS. Utilizarás la aplicación Hola Mundo en la nube creada en la Receta 4.1 para habilitar tu dominio personalizado.
Nota
Necesitarás un dominio personalizado para esta receta.
En Google Cloud Console, ve a App Engine > Configuración > Dominios personalizados.
Haz clic en Añadir un dominio personalizado.
Si se ha verificado tu nombre de dominio, éste aparecerá en el menú desplegable. Selecciona el dominio en el menú desplegable y haz clic en Continuar.
Si no has verificado tu nombre de dominio en , sigue estos pasos para verificarlo:
Selecciona Verificar un nuevo dominio en el menú desplegable.
Introduce tu nombre de dominio y haz clic en Verificar.
Introduce la información necesaria en la página Webmaster.
Después de completar estos pasos en la página Webmaster, volverás a la página Añadir un nuevo dominio personalizado en Google Cloud Console.
En la sección "Apunta tu dominio a", añade el dominio o subdominio que quieras mapear. Haz clic en Guardar asignaciones, como se muestra en la Figura 4-4.
Haz clic en Continuar para ver los registros DNS de tu dominio.
Accede al sitio web de tu registrador de dominios y actualiza tus registros DNS con los registros que se muestran.
Pruébalo abriendo tu navegador web en tu dominio recién mapeado.
Nota
El certificado SSL puede tardar varios minutos en emitirse.
Debate
Al mapear un dominio personalizado, puedes permitir que tu aplicación App Engine se alinee con tu marca, así como mantener un sitio seguro, ya que Google Cloud proporcionará un certificado SSL para tu dominio mapeado. Los certificados gestionados de Google Cloud no admiten dominios comodín; si necesitas dominios comodín, tendrás que utilizar certificados autogestionados .
4.5 Uso de las API de aprendizaje automático de Google Cloud Translation con App Engine
Solución
Google Cloud ofrece una Media Translation API que añade traducción de audio en tiempo real a tus aplicaciones. En esta receta crearás dos aplicaciones, una aplicación de difusión y una aplicación cliente, utilizando App Engine para alojar tu aplicación.
La Figura 4-5 muestra una arquitectura de alto nivel de la aplicación que vas a implementar.
LaFigura 4-6 es la aplicación de difusión que utiliza el presentador.
La Figura 4-7 es la aplicación cliente donde los usuarios pueden ver los subtítulos traducidos.
Esta receta requiere que utilices en el comando git clone
para el repositorio de ejemplos de código de este libro.
En la aplicación clonada, ve a 04-appengine/4-5-media.
En tu IDE, edita el archivo client/client.js y sustituye [PROJECT_ID] por tu proyecto de Google Cloud:
const socket = io.connect('https://[YOUR_PROJECT_ID].uc.r.appspot.com');
Repite el proceso del paso 2 pero edita el archivo broadcast/client.js.
Activa la API de Traducción de Medios en la Consola de Google Cloud.
Implementación tu aplicación App Engine ejecutando el comando
gcloud app deploy
comando. En el archivo app.js del directorio raíz, verás que se declaran las siguientes rutas Expres.js. La ruta cliente es para los usuarios que lean las traducciones de la persona que emite. La persona que emite visitaría la raíz de la aplicación App Engine:app.use('/', express.static('broadcast')) app.use('/client', express.static('client'))
Una vez desplegada tu aplicación, visita la ruta raíz y abre una nueva pestaña con la ruta /cliente.
En la aplicación de transmisión, haz clic en Empezar a traducir y empieza a hablar en inglés; observa la traducción en la segunda pestaña. La traducción es del inglés al portugués.
Puedes cambiar los idiomas en el archivo app.js, líneas 29 y 30:
const sourceLanguage = 'en-US'; const targetLanguage = 'pt-BR';
Debate
En esta receta, has utilizado un repositorio existente para implementar una aplicación de traducción en App Engine. Esta aplicación utiliza Express.js, WebSockets y la Media Translation API para permitir la traducción de audio en tiempo real al idioma que definas en el código. Como estamos utilizando WebSockets, utilizamos App Engine Flexible, porque Standard no admite WebSockets. Los WebSockets permitieron la comunicación en tiempo real de la emisora y usuarios.
4.6 Construir interfaces de usuario para ver tablas y gráficos
Solución
Utiliza App Engine, junto con Cube.js, BigQuery y App Engine para construir una interfaz de usuario(Figura 4-8) para ver tablas y gráficos a partir de los datos almacenados en tu conjunto de datos BigQuery. BigQuery es un almacén de datos totalmente gestionado y sin servidor.
Nota
Utilizarás Cube.js, que es una plataforma API analítica de código abierto.
También aprenderás a implementar React.js en App Engine, ya que los paneles de usuario se ejecutarán con el framework React.js.
En tu estación de trabajo local, crea una carpeta temporal para guardar los archivos que necesitarás para crear los paneles de usuario de App Engine.
En tu carpeta temporal, utilizando la CLI de Cube.js, ejecuta el comando
npx cubejs-cli create real-time-dashboard -d bigquery
para crear una nueva aplicación Cube.js para BigQuery.Necesitarás credenciales para acceder a BigQuery. En Google Cloud Console, crea una nueva cuenta de servicio. Añade los roles Visor de datos de BigQuery y Usuario de trabajos de BigQuery a esta cuenta de servicio y, a continuación, genera un nuevo archivo de clave JSON. Copia la clave JSON en la raíz de la carpeta real-time-dashboard.
En tu IDE, edita el archivo real-time-dashboard/.env para incluir tu proyecto de Google Cloud, así como la ubicación de tu archivo clave:
CUBEJS_DB_BQ_PROJECT_ID=example-google-project CUBEJS_DB_BQ_KEY_FILE=./examples.json CUBEJS_DB_TYPE=bigquery CUBEJS_API_SECRET=SECRET
Cube.js utiliza un esquema de datos para generar código SQL. Trabajarás con el conjunto de datos públicos BigQuery Hacker News. Crea un archivo llamado Stories.js en la carpeta real-time-dashboard/schema con el siguiente código:
cube(`Stories`, { sql: ` SELECT * FROM bigquery-public-data.hacker_news.full WHERE type = "story" AND STARTS_WITH(UPPER(url), "HTTP") `, measures: { count: { type: `count`, }, }, dimensions: { protocol: { sql: `UPPER(REGEXP_EXTRACT(${CUBE}.url, r"^([a-zA-Z]+):"))`, type: `string`, }, time: { sql: `timestamp`, type: `time`, }, }, });
Ahora ejecuta localmente un panel de control en tiempo real para probar y validar que funciona como se espera. Ejecuta en el comando
npm run dev
en la carpeta del panel de control en tiempo real.En tu navegador, ve a http://localhost:4000, que debería lanzar Cube.js Playground, como se muestra en la Figura 4-9.
Para comprobar que se está conectando a BigQuery, haz clic en Medir y elige Recuento de Historias, como se muestra en la Figura 4-10.
Este servicio se convertirá en una API que se ejecutará en App Engine. El panel de control del usuario se conectará a la API de Cube.js para obtener los datos necesarios y visualizarlos para el usuario.
Para construir el panel de control, haz clic en la App Panel de Control en el Playground de Cube.js.
Una vez instalada, localiza la carpeta en tu IDE; estará en real-time-dashboard/dashboard-app.
En tu IDE, edita el archivo src/pages/DashboardPage.js para sustituir la siguiente línea:
const DashboardItems = []
con:
const DashboardItems = [ { id: 0, name: "Orders Status by Customers City", vizState: { query: { "measures": [ "Stories.count" ], "timeDimensions": [], "order": { "Stories.count": "desc" }, "dimensions": [ "Stories.protocol" ] }, chartType: "pie", } }, { id: 1, name: "Orders Status by Customers City", vizState: { query: { "measures": [ "Stories.count" ], "timeDimensions": [ { "dimension": "Stories.time", "granularity": "year" } ], "order": {}, "dimensions": [] }, chartType: "line", } }, ];
En tu IDE, edita src/components/ChartRenderer.js para incluir lo siguiente:
const ChartRenderer = ({ - vizState + vizState, cubejsApi - const renderProps = useCubeQuery(query); + const renderProps = useCubeQuery(query, { subscribe: true, cubejsApi });
Nota
Elimina las líneas de CharRenderer.js señaladas con el símbolo de resta (-) y añade las señaladas con el símbolo de suma (+).
Para saber más sobre Cube.js y React, visita la referencia en línea.
Crea un archivo app.yaml en real-time-dashboard/dashboard-app con el siguiente código:
runtime: nodejs14 handlers: - url: /(.*\..+)$ static_files: build/\1 upload: build/(.*\..+)$ - url: /.* static_files: build/index.html upload: build/index.html
Esta configuración permite a App Engine servir la compilación optimizada de React.js. Cuando realices cambios, siempre tendrás que ejecutar una compilación npm run antes de implementar tu nueva versión en App Engine.
Ejecuta los siguientes comandos para implementar el Panel de control en App Engine:
npm run build gcloud app deploy
Una vez que se haya implementado correctamente, ejecuta el comando
gcloud app browse
para ver la aplicación en tu navegador.Copia la URL de tu aplicación de panel de control implementada y edita el archivo real-time-dashboard/dashboard-app/App.js para sustituir la variable
const API_URL
por la tuya. Debería tener este aspecto:const API_URL = "https://ruicosta-blog.uc.r.appspot.com";
Adelante, vuelve a desplegarte:
npm run build gcloud app deploy
En este punto, el Panel de Control está listo para conectarse a la API Cube.js que acabas de actualizar en el archivo App.js. Ahora es el momento de implementar la API en App Engine.
Crea un Dockerfile en la carpeta real-time-dashboard con el siguiente código:
FROM cubejs/cube:latest COPY . .
Crea un archivo app.yaml en la carpeta real-time-dashboard con el siguiente código:
runtime: custom env: flex service: api
Como Cube.js utiliza WebSockets y App Engine Standard no admite WebSockets, necesitamos utilizar un tiempo de ejecución personalizado, por lo que utilizarás Flexible para la API.
Actualiza el contenido del archivo cube.js con lo siguiente, situado en la raíz de la carpeta real-time-dashboard:
module.exports = { processSubscriptionsInterval: 1, orchestratorOptions: { queryCacheOptions: { refreshKeyRenewalThreshold: 1, } }, };
Actualiza el contenido del archivo .env con lo siguiente, situado en la raíz de la carpeta real-time-dashboard, para incluir
CUBEJS_WEB_SOCKETS=true
.Crea un nuevo archivo, llamado dispatch.yaml, en la raíz de la carpeta real-time-dashboard:
- url: "*/cubejs-api*" service: api
El archivo dispatch.yaml te permite anular las reglas de enrutamiento y permite que tu aplicación del Panel de control acceda a la API a través de la URL principal del Panel de control para no causar problemas con CORS.
Ya estás preparado para implementar la API y hacer que los usuarios accedan a los datos a través del Panel de control. En la raíz del panel de control en tiempo real, ejecuta el comando
gcloud app deploy
para implementar la API.Una vez completado esto, implementa las reglas de envío ejecutando
gcloud app deploy dispatch.yaml
.Si ahora accedes a la URL del Panel de Control, deberías poder ver lo que se muestra en la Figura 4-11.
No olvides proteger tu aplicación activando el IAP.
Debate
En esta receta, has implementado la API Cube.js, un panel de control de usuario que se ejecuta en el framework React.js, en App Engine y has creado rutas con reglas de envío para crear un panel de control interactivo en tiempo real para los usuarios.
Hay muchas partes móviles en esta receta, pero los puntos clave son:
4.7 Depurar una instancia
Solución
Con App Engine Flexible, activa el modo de depuración. Mientras la depuración está activada, puedes acceder a la VM para ver los archivos de registro de tu tiempo de ejecución personalizado.
Para activar el modo de depuración, ejecuta el comando gcloud
app --project PROJECT_ID
.Te indicará las instancias disponibles para habilitar la depuración. Elige una.
En Google Cloud Console, selecciona App Engine > Instancias.
Deberías darte cuenta de que en la instancia que elegiste ahora está activado el modo Depuración(Figura 4-12).
Pulsa el botón SSH para conectarte a la instancia.
En este punto, estás conectado al host de instancia, que tiene varios contenedores ejecutándose en él.
Nota
Además de tu contenedor ejecutándose en App Engine Flexible, también tendrás tres contenedores adicionales:
Fluentd Agente de registro
Agente proxy Memcache
Proxy NGINX
Ejecuta
sudo docker ps
para listar los contenedores en ejecución.La salida del comando
sudo docker ps
enumera cada contenedor; localiza la fila que contiene el ID de tu proyecto y anota el NOMBRE de este contenedor.Para ver los registros, ejecuta el comando
sudo docker logs [CONTAINER-NAME]
comandoEsto te permite ver los registros de tu aplicación con fines de depuración.
También puedes conectarte a la instancia ejecutando
sudo docker exec -it CONTAINER_NAME /bin/bash
.Cuando hayas terminado, no olvides desactivar la depuración ejecutando el comando
gcloud app --project PROJECT_ID instances disable-debug
.
4.8 Utilizar CI/CD
Solución
Utiliza GitLab CI/CD, una herramienta que te permite aplicar a tu aplicación la integración continua (CI), la entrega continua (CD) y la implementación continua (también CD).
Crea un nuevo proyecto GitLab y clona el nuevo repositorio en tu máquina local.
Crea la aplicación Hola Mundo de la Receta 4.1, pero no la despliegues en App Engine.
En la raíz del directorio, crea un archivo GitLab CI/CD llamado.gitlab-ci.yml con el siguiente contenido:
image: google/cloud-sdk:slim deploy: stage: deploy environment: Production only: - master script: - gcloud auth activate-service-account --key-file $GOOGLE_SERVICE_ACCOUNT_FILE - gcloud app deploy app.yaml --quiet --project $GOOGLE_PROJECT_ID --version 1
En la Consola de Google Cloud, ve a Identidad > Cuentas de servicio.
Haz clic en Crear cuenta de servicio.
Introduce el nombre y la descripción y haz clic en Crear.
Selecciona el rol de Editor y haz clic en Continuar.
Selecciona la cuenta de servicio que acabas de crear y, en Opciones, haz clic en Crear una clave en formato JSON. Descarga la clave a tu estación de trabajo local.
En la consola de GitLab dentro de tu proyecto, ve a Configuración > CI/CD.
Amplía la sección Variables.
Crea una nueva variable.
Cambia el tipo de variable a Archivo. La clave se llamará GOOGLE_SERVICE_ACCOUNT_FILE, y el valor será el contenido del archivo que se ha descargado previamente.
Crea otra variable, llamada GOOGLE_PROJECT_ID, y el valor será el ID del proyecto de Google Cloud.
Confirma tu código y despliega tu aplicación en App Engine. Además, confirma tus cambios en tu repositorio de GitLab.
En la consola de GitLab, abre la página GitLab CI/CD. Verás que tu pipeline se está ejecutando.
Si haces clic en la canalización, verás los pasos de la implementación; observa Trabajo realizado con éxito.
Debate
Las metodologías continuas de desarrollo de software se basan en automatizar las pruebas e implementaciones de tu código fuente para minimizar la posibilidad de errores. GitLab CI/CD proporciona un conjunto de herramientas, incluida la metodología de implementación continua utilizada en esta receta. Ahora, en lugar de desplegar tu aplicación manualmente, puede desplegarse automáticamente en Google Cloud App Engine.
Get Libro de cocina de Google Cloud now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.