1. Descripción general
En este lab, se demuestran las funciones y capacidades diseñadas para optimizar el flujo de trabajo de desarrollo de los ingenieros de software encargados de desarrollar aplicaciones de NodeJS en un entorno alojado en contenedores. El desarrollo de contenedores típico requiere que el usuario comprenda los detalles de los contenedores y el proceso de compilación de contenedores. Además, los desarrolladores suelen tener que interrumpir su flujo de trabajo y salir del IDE para probar y depurar sus aplicaciones en entornos remotos. Con las herramientas y tecnologías que se mencionan en este instructivo, los desarrolladores pueden trabajar de manera eficaz con aplicaciones en contenedores sin salir de su IDE.
Qué aprenderás
En este lab, aprenderás métodos para desarrollar con contenedores en GCP, incluidos los siguientes:
- Cómo crear una aplicación inicial de Node.js
- Configura la aplicación de Node.js para el desarrollo de contenedores
- Cómo codificar un servicio REST de CRUD simple
- Implementar en GKE
- Cómo depurar un estado de error
- Utilización de registros y puntos de interrupción
- Implementación en caliente de los cambios en GKE
- Opcional: Integra Cloud SQL para la persistencia del backend
2. Configuración y requisitos
Cómo configurar el entorno a tu propio ritmo
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.



- El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una string de caracteres que no se utiliza en las API de Google y se puede actualizar en cualquier momento.
- El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). Cloud Console genera automáticamente una string única, que, por lo general, no importa cuál sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (suele ser
PROJECT_ID). Por lo tanto, si no te gusta, genera otro aleatorio o prueba con uno propio y comprueba si está disponible. Después de crear el proyecto, este ID se “congela” y no se puede cambiar. - Además, hay un tercer valor, el Número de proyecto, que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás habilitar la facturación en Cloud Console para usar las API o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Si quieres cerrar los recursos para no se te facture más allá de este instructivo, sigue las instrucciones de “limpieza” que se encuentran al final del codelab. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.
Inicia el editor de Cloud Shell
Este lab se diseñó y probó para usarse con el Editor de Google Cloud Shell. Para acceder al editor, haz lo siguiente:
- Accede a tu proyecto de Google en https://console.cloud.google.com.
- En la esquina superior derecha, haz clic en el ícono del editor de Cloud Shell.

- Se abrirá un panel nuevo en la parte inferior de la ventana.
- Haz clic en el botón Abrir editor.

- El editor se abrirá con un explorador a la derecha y un editor en el área central.
- También debería haber un panel de terminal disponible en la parte inferior de la pantalla.
- Si la terminal NO está abierta, usa la combinación de teclas "Ctrl + `" para abrir una ventana de terminal nueva.
Configura gcloud
En Cloud Shell, establece el ID del proyecto y la región en la que deseas implementar tu aplicación. Guárdalos como variables PROJECT_ID y REGION.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
Configura el clúster y la base de datos de GKE
- Descarga la secuencia de comandos de configuración y haz que sea ejecutable.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/setup.sh
chmod +x setup.sh
Aprovisiona la infraestructura que se usa en este lab
En este lab, implementarás código en GKE y accederás a los datos almacenados en una base de datos de Spanner. La siguiente secuencia de comandos de configuración prepara esta infraestructura por ti.
- Abre el archivo
setup.shy edita los valores de las contraseñas que actualmente están configuradas como CHANGEME. - Ejecuta la secuencia de comandos de configuración para crear un clúster de GKE y una base de datos de Cloud SQL que usarás en este lab.
./setup.sh
- En Cloud Shell, crea un directorio nuevo con el nombre
mynodejsapp.
mkdir mynodejsapp
- Cambia a este directorio y ábrelo como un lugar de trabajo. Esto volverá a cargar el editor creando una configuración del lugar de trabajo en la carpeta recién creada.
cd mynodejsapp && cloudshell workspace .
- Instala Node y NPM con NVM.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# This loads nvm bash_completion
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
nvm install stable
nvm alias default stable
3. Crea una nueva aplicación inicial
- Inicializa la aplicación
Crea un archivo package.json ejecutando el siguiente comando.
npm init
Choose the entry point: (index.js) src/index.js and default values for the rest of the parameters. This will create the file with following contents
{
"name": "mynodejsapp",
"version": "1.0.0",
"description": "",
"main": "src/index.js",,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
- Cómo agregar un punto de entrada
Edita este archivo para incluir el comando de inicio en el script "start": "node src/index.js",. Después del cambio, los secuencias de comandos deberían verse como el siguiente fragmento de código:
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
- Cómo agregar la dependencia de Express
El código que agregaremos también usa express, así que agreguemos esa dependencia a este archivo package.json. Por lo tanto, después de todos los cambios, el archivo package.json debería verse como se muestra a continuación.
{
"name": "mynodejsapp",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Your Name",
"license": "ISC",
"dependencies": {
"express": "^4.16.4"
}
}
- Crea el archivo index.js
Crea un directorio de origen llamado src
Crea src/index.js con el siguiente código
const express = require('express');
const app = express();
const PORT = 8080;
app.get('/', (req, res) => {
var message="Greetings from Node";
res.send({ message: message });
});
app.listen(PORT, () => {
console.log(`Server running at: http://localhost:${PORT}/`);
});
Ten en cuenta que el PUERTO está establecido en el valor 8080.
Generar manifiestos
Skaffold proporciona herramientas integradas para simplificar el desarrollo de contenedores. En este paso, inicializarás Skaffold, que creará automáticamente archivos YAML base de Kubernetes. Ejecuta el siguiente comando para comenzar el proceso.
Ejecuta el siguiente comando en la terminal
skaffold init --generate-manifests
Realice las siguientes acciones cuando se le solicite:
- Ingresa 8080 para el puerto.
- Ingresa y para guardar la configuración.
Se agregan dos archivos a la visualización del espacio de trabajo, skaffold.yaml y deployment.yaml.
Actualiza el nombre de la app
Actualmente, los valores predeterminados incluidos en la configuración no coinciden con el nombre de tu aplicación. Actualiza los archivos para que hagan referencia al nombre de tu aplicación en lugar de los valores predeterminados.
- Cambia las entradas en la configuración de Skaffold
- Abrir
skaffold.yaml - Selecciona el nombre de la imagen que está configurado actualmente como
package-json-image. - Haz clic con el botón derecho y elige Cambiar todas las ocurrencias.
- Escribe el nombre nuevo como
mynodejsapp
- Cambia las entradas en la configuración de Kubernetes
- Abre el archivo
deployment.yaml. - Selecciona el nombre de la imagen que está configurado actualmente como
package-json-image. - Haz clic con el botón derecho y elige Cambiar todas las ocurrencias.
- Escribe el nombre nuevo como
mynodejsapp
Ten en cuenta que, en el archivo skaffold.yaml, la sección build usa buildpacks para contener la aplicación. Este código no tiene Dockerfile y el desarrollador no necesita ningún conocimiento de Docker para contenerizar esta aplicación.
Además, esta configuración de Skaffold habilita automáticamente la sincronización activa entre el editor y el contenedor en ejecución. No se requiere ninguna configuración adicional para habilitar la sincronización rápida.
4. Explicación del proceso de desarrollo
En esta sección, seguirás algunos pasos con el complemento de Cloud Code para aprender los procesos básicos y validar la configuración de tu aplicación de inicio.
Cloud Code se integra en Skaffold para optimizar tu proceso de desarrollo. Cuando realices la implementación en GKE en los siguientes pasos, Cloud Code y Skaffold compilarán automáticamente tu imagen de contenedor, la enviarán a Container Registry y, luego, implementarán tu aplicación en GKE. Esto sucede en segundo plano, abstrayendo los detalles del flujo del desarrollador. Cloud Code también mejora tu proceso de desarrollo, ya que proporciona capacidades tradicionales de depuración y sincronización en caliente para el desarrollo basado en contenedores.
Implementar en Kubernetes
- En el panel que se encuentra en la parte inferior del editor de Cloud Shell, selecciona Cloud Code. 

- En el panel que aparece en la parte superior, selecciona Run on Kubernetes. Si se te solicita, selecciona Sí para usar el contexto actual de Kubernetes.

- La primera vez que ejecutes el comando, aparecerá un mensaje en la parte superior de la pantalla que te preguntará si deseas el contexto actual de Kubernetes. Selecciona "Sí" para aceptar y usar el contexto actual.

- A continuación, se mostrará un mensaje en el que se preguntará qué registro de contenedores usar. Presiona Intro para aceptar el valor predeterminado proporcionado.

- Selecciona la pestaña Output en el panel inferior para ver el progreso y las notificaciones.

- Selecciona "Kubernetes: Run/Debug - Detailed" en el menú desplegable del canal a la derecha para ver detalles adicionales y registros que se transmiten en vivo desde los contenedores.

- Para volver a la vista simplificada, selecciona "Kubernetes: Run/Debug" en el menú desplegable.
- Cuando finalicen la compilación y las pruebas, la pestaña Output dirá:
Resource deployment/mynodejsapp status completed successfullyy se mostrará una URL: "Forwarded URL from service demo-app: http://localhost:8080". - En la terminal de Cloud Code, coloca el cursor sobre la URL en el resultado (http://localhost:8080) y, luego, en la información sobre herramientas que aparece, selecciona Abrir en la vista previa web.
La respuesta será la siguiente:
{"message":"Greetings from Node"}
Recarga en caliente
- Navega a
src/index.js. Edita el código del mensaje de saludo a'Hello from Node'
Observa de inmediato que, en la ventana Output, vista Kubernetes: Run/Debug, el observador sincroniza los archivos actualizados con el contenedor en Kubernetes.
Update initiated File sync started for 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a File sync succeeded for 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Update succeeded
- Si cambias a la vista
Kubernetes: Run/Debug - Detailed, notarás que reconoce los cambios en el archivo y reinicia el nodo.
files modified: [src/index.js] Copying files:map[src/index.js:[/workspace/src/index.js]]togcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Syncing 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Watching for changes... [mynodejsapp] [mynodejsapp]> mynodejsapp@1.0.0 start /workspace [mynodejsapp]> node src/index.js [mynodejsapp] [mynodejsapp]Server running at: http://localhost:8080/
- Actualiza el navegador para ver los resultados actualizados.
Depuración
- Ve a la vista de depuración y detén el subproceso actual
. - Haz clic en
Cloud Codeen el menú inferior y seleccionaDebug on Kubernetespara ejecutar la aplicación en mododebug.
- En la vista
Kubernetes Run/Debug - Detailedde la ventanaOutput, observa que Skaffold implementará esta aplicación en modo de depuración. - La compilación y la implementación de la aplicación tardarán unos minutos. Esta vez, verás un depurador adjunto.
Port forwarding pod/mynodejsapp-6bbcf847cd-vqr6v in namespace default, remote port 9229 -> http://127.0.0.1:9229 [mynodejsapp]Debugger attached.
- La barra de estado inferior cambia su color de azul a naranja, lo que indica que está en modo de depuración.
- En la vista
Kubernetes Run/Debug, observa que se inició un contenedor depurable.
**************URLs***************** Forwarded URL from service mynodejsapp-service: http://localhost:8080 Debuggable container started pod/mynodejsapp-deployment-6bc7598798-xl9kj:mynodejsapp (default) Update succeeded ***********************************
Utiliza puntos de interrupción
- Abre
src/index.js - Ubica la instrucción que dice
var message="Greetings from Node";. - Para agregar un punto de interrupción a esa línea, haz clic en el espacio en blanco a la izquierda del número de línea. Aparecerá un indicador rojo para señalar que se estableció el punto de interrupción.
- Vuelve a cargar el navegador y observa que el depurador detiene el proceso en el punto de interrupción y te permite investigar las variables y el estado de la aplicación que se ejecuta de forma remota en GKE.
- Haz clic en la sección de variables hasta que encuentres la variable
"message". - Presiona Step over
para ejecutar la línea. - Observa el cambio del valor actual de la variable
"message"a"Greetings from Node". - Haz doble clic en el nombre de la variable "target" y, en la ventana emergente, cambia el valor a algo diferente, como
"Hello from Node". - Haz clic en el botón Continuar en el panel de control de depuración.
- Revisa la respuesta en tu navegador, que ahora muestra el valor actualizado que acabas de ingresar.
- Para detener el modo "Depuración", presiona el botón de detener
y quita el punto de interrupción haciendo clic en él de nuevo.
5. Cómo desarrollar un servicio REST de CRUD simple
En este punto, tu aplicación está completamente configurada para el desarrollo en contenedores y ya completaste el flujo de trabajo de desarrollo básico con Cloud Code. En las siguientes secciones, practicarás lo que aprendiste agregando extremos de servicio de REST que se conectan a una base de datos administrada en Google Cloud.
Configura dependencias
El código de la aplicación usa una base de datos para conservar los datos del servicio de REST. Para asegurarte de que las dependencias estén disponibles, agrega lo siguiente al archivo package.json:
- Agrega dos dependencias más,
pgysequelize, al archivopackage.jsonpara compilar una aplicación CRUD de Postgres. Después de los cambios, la sección de dependencias se verá de la siguiente manera.
"dependencies": {
"express": "^4.16.4",
"pg": "^8.7.3",
"sequelize": "^6.17.0"
}
Codifica el servicio de REST
- Agrega el código de la aplicación CRUD a esta aplicación
wget -O app.zip https://github.com/GoogleCloudPlatform/container-developer-workshop/raw/main/labs/nodejs/app.zip
unzip app.zip
Este código tiene
- Carpeta models con el modelo de entidad para
item - Carpeta controllers con el código que realiza operaciones de CRUD
- Carpeta routes que enruta patrones de URL específicos a diferentes llamadas
- Carpeta config con detalles de conectividad de la base de datos
- Ten en cuenta que la configuración de la base de datos en el archivo
db.config.jshace referencia a las variables de entorno que se deben proporcionar para conectarse a la base de datos. También debes analizar la solicitud entrante para la codificación de URL. - Agrega el siguiente fragmento de código en
src/index.jspara poder conectarte al código CRUD desde tu archivo JavaScript principal justo antes de la última sección que comienza conapp.listen(PORT, () => {.
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true,
})
)
const db = require("../app/models");
db.sequelize.sync();
require("../app/routes/item.routes")(app);
- Edita la implementación en el archivo
deployment.yamlpara agregar las variables de entorno que proporcionarán la información de conectividad de la base de datos.
Actualiza la entrada de especificaciones al final del archivo para que coincida con la siguiente definición
spec:
containers:
- name: mynodejsapp
image: mynodejsapp
env:
- name: DB_HOST
value: ${DB_INSTANCE_IP}
- name: DB_PORT
value: "5432"
- name: DB_USER
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: database
- Reemplaza el valor de DB_HOST por la dirección de tu base de datos.
export DB_INSTANCE_IP=$(gcloud sql instances describe mytest-instance \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
envsubst < deployment.yaml > deployment.new && mv deployment.new deployment.yaml
Implementa y valida la aplicación
- En el panel que se encuentra en la parte inferior del Editor de Cloud Shell, selecciona
Cloud Codey, luego,Debug on Kubernetesen la parte superior de la pantalla. - Cuando finalicen la compilación y las pruebas, la pestaña Output dirá:
Resource deployment/mynodejsapp status completed successfullyy se mostrará la URL "Forwarded URL from service mynodejsapp: http://localhost:8080". - Agrega algunos elementos.
Desde la terminal de Cloud Shell, ejecuta los siguientes comandos:
URL=localhost:8080
curl -X POST $URL/items -d '{"itemName":"Body Spray", "itemPrice":3.2}' -H "Content-Type: application/json"
curl -X POST $URL/items -d '{"itemName":"Nail Cutter", "itemPrice":2.5}' -H "Content-Type: application/json"
- Para probar el método GET, ejecuta $URL/items en el navegador. También puedes ejecutar curl desde la línea de comandos.
curl -X GET $URL/items
- Prueba de borrado: Ahora intenta borrar un elemento ejecutando. Cambia el valor de item-id si es necesario.
curl -X DELETE $URL/items/1
This throws an error message
{"message":"Could not delete Item with id=[object Object]"}
Identifica y corrige el problema
- Reinicia la aplicación en modo de depuración y busca el problema. A continuación, se incluyen algunas sugerencias:
- Sabemos que hay un problema con la instrucción DELETE, ya que no devuelve el resultado deseado. Por lo tanto, establecerías el punto de interrupción en el método
itemcontroller.js->exports.delete. - Ejecuta paso a paso y observa las variables en cada paso para ver los valores de las variables locales en la ventana de la izquierda.
- Para observar valores específicos, como
request.params, agrega esta variable a la ventana Watch.
- Ten en cuenta que el valor asignado a
idesundefined. Cambia el código para solucionar el problema.
El fragmento de código corregido se vería de la siguiente manera:
// Delete a Item with the specified id in the request
exports.delete = (req, res) => {
const id = req.params.id;
- Una vez que se reinicie la aplicación, vuelve a probar si se puede borrar.
- Para detener la sesión de depuración, haz clic en el cuadrado rojo de la barra de herramientas de depuración.

6. Limpieza
¡Felicitaciones! En este lab, creaste una nueva aplicación de Node.js desde cero y la configuraste para que funcione en modo de implementación activa con contenedores. Luego, implementaste y depuraste tu aplicación en un clúster de GKE remoto siguiendo el mismo flujo de desarrollador que se encuentra en las pilas de aplicaciones tradicionales.
Para limpiar después de completar el lab, haz lo siguiente:
- Borra los archivos que se usaron en el lab
cd ~ && rm -rf mynodejsapp && rm -f setup.sh
- Borra el proyecto para quitar toda la infraestructura y los recursos relacionados