Entorno de ejecución de Node.js

El tiempo de ejecución de Node.js es la pila de software encargada de instalar el código de tu aplicación y sus dependencias, y, a continuación, ejecutar esa aplicación en el entorno flexible.

Versiones de Node.js

Node.js 24 (vista previa) usa buildpacks. El motor de Node.js predeterminado usa la versión LTS más reciente. Para ver la lista completa de las versiones de Node.js admitidas y sus correspondientes versiones de Ubuntu, consulta el calendario de asistencia de tiempo de ejecución.

Para usar una versión compatible de Node.js, debes hacer lo siguiente:

  • Instala la versión 420.0.0 o una posterior de gcloud CLI. Puedes actualizar tus herramientas de CLI ejecutando el comando gcloud components update. Para ver la versión instalada, ejecuta el comando gcloud version.

  • Incluya los ajustes runtime_config y operating_system en el archivo app.yaml para especificar un sistema operativo.

  • Si quieres, puedes especificar una versión de las siguientes formas:

    • Añadir el ajuste runtime_version en el archivo app.yaml. De forma predeterminada, se usa la versión más reciente de Node.js si no se especifica el ajuste runtime_version. Por ejemplo:

      • Para especificar Node.js 24 (vista previa) en Ubuntu 24, haz lo siguiente:

          runtime: nodejs
          env: flex
        
          runtime_config:
              operating_system: "ubuntu24"
              runtime_version: "24"
        
      • Para especificar la versión más reciente compatible de Node.js en Ubuntu 24, sigue estos pasos:

          runtime: nodejs
          env: flex
        
          runtime_config:
              operating_system: "ubuntu24"
        

        El ajuste runtime_version admite semver.

    • Incluye la versión más reciente compatible de Node.js en el archivo package.json de tu aplicación mediante el campo engines. Cuando se usa el campo engines para especificar una versión, el ajuste runtime_version tiene prioridad. Para evitar fallos inesperados, te recomendamos que especifiques una versión de Node.js en el campo engines, junto con runtime_version. Por ejemplo:

        {
          "engines": {
            "node": "24.x"
          }
        }
      

      La propiedad engines.node puede ser un intervalo de versiones semánticas. Si especificas esta propiedad, el tiempo de ejecución descarga e instala la versión más reciente de Node.js que coincida con el intervalo de semver. Si no se encuentra ninguna coincidencia, la aplicación no se podrá implementar y el tiempo de ejecución devolverá un error.

Versiones anteriores del entorno de ejecución

En el caso del tiempo de ejecución de Node.js versión 16 y anteriores, especifica una versión en el archivo package.json de tu aplicación mediante el campo engines.

En el siguiente ejemplo se configura el tiempo de ejecución para usar la versión 9 de Node:

{
  "engines": {
    "node": "9.x"
  }
}

La propiedad engines.node puede ser un intervalo de versiones semánticas. Si especificas esta propiedad, el tiempo de ejecución descarga e instala la versión más reciente de Node.js que coincida con el intervalo de semver. Si no se encuentra ninguna coincidencia, la aplicación no se desplegará y el tiempo de ejecución devolverá un mensaje de error.

Compatibilidad con otros entornos de ejecución de Node.js

Si necesitas usar una versión de Node.js que no sea compatible, puedes crear un entorno de ejecución personalizado y seleccionar una imagen base válida con la versión de Node.js que necesites.

Para obtener información sobre las imágenes base proporcionadas por Google o las imágenes base de Docker Node.js, consulta Crear entornos de ejecución personalizados.

Gestor de paquetes

Durante la implementación, el tiempo de ejecución usa el gestor de paquetes npm, yarn o Pnpm para instalar las dependencias e iniciar la aplicación. El gestor de paquetes se configura con la siguiente lógica:

  • El gestor de paquetes predeterminado es npm.
  • Si hay un archivo yarn.lock en el directorio raíz de tu aplicación, el tiempo de ejecución usará el gestor de paquetes yarn.
  • Solo en Node.js 18 y versiones posteriores, si hay un archivo pnpm-lock.yaml en el directorio raíz de tu aplicación, el tiempo de ejecución usará el gestor de paquetes Pnpm.
  • Si existen tanto package-lock.json como yarn.lock o pnpm-lock.yaml, la implementación fallará y se producirá un error. Si necesitas el archivo package-lock.json, debes especificar los demás archivos del gestor de paquetes en la sección skip_files del archivo app.yaml para determinar qué gestor de paquetes usar.

Versión del gestor de paquetes

La imagen de tiempo de ejecución tiene como objetivo usar la última versión yarn y la versión de npm que está disponible en la última versión LTS de Node.js.

Puedes especificar otra versión del gestor de paquetes que quieras usar en el archivo package.json de tu aplicación mediante el campo engines. En este caso, el tiempo de ejecución se asegura de que el gestor de paquetes utilizado para la implementación tenga una versión que coincida con la especificación indicada en el campo engines.

Si se proporciona una especificación de versión de yarn y npm, solo se actualizará el gestor de paquetes que se utilice para la implementación, si es necesario. De esta forma, se ahorra tiempo de implementación, ya que no se instala una versión personalizada de un gestor de paquetes si no se va a usar para implementar tu aplicación.

En el siguiente ejemplo se configura el tiempo de ejecución para usar una versión personalizada de npm:

{
  "engines": {
    "npm": "5.x"
  }
}

En el siguiente ejemplo se configura el tiempo de ejecución para usar una versión personalizada de yarn:

{
  "engines": {
    "yarn": ">=1.0.0 <2.0.0"
  }
}

Las propiedades engines.npm y engines.yarn pueden ser un intervalo de versiones semánticas.

Dependencias

Durante la implementación, el tiempo de ejecución usará el gestor de paquetes npm o yarn para instalar las dependencias ejecutando npm install o yarn install. Consulta la sección Gestor de paquetes para obtener más información sobre cómo selecciona el tiempo de ejecución el gestor de paquetes que se va a usar.

Además, para obtener más información sobre cómo gestionar paquetes de Node.js en Google App Engine, consulta Usar bibliotecas de Node.js.

Para habilitar el uso de paquetes de Node.js que requieren extensiones nativas, los siguientes paquetes de Ubuntu están preinstalados en la imagen de Docker.

  • build-essential
  • ca-certificates
  • curl
  • git
  • imagemagick
  • libkrb5-dev
  • netbase
  • python

Si tu aplicación requiere dependencias adicionales a nivel de sistema operativo, tendrás que usar un tiempo de ejecución personalizado basado en este tiempo de ejecución para instalar los paquetes adecuados.

Secuencia de comandos de compilación de NPM

En el entorno de ejecución de Node.js versión 18 y posteriores, el entorno de ejecución ejecuta npm run build si se detecta una secuencia de comandos build en package.json de forma predeterminada. Si necesitas tener más control sobre los pasos de compilación antes de iniciar la aplicación, puedes proporcionar un paso de compilación personalizado añadiendo una secuencia de comandos gcp-build al archivo package.json.

Para evitar que tu compilación ejecute la secuencia de comandos npm run build, debes hacer lo siguiente:

  • Añade una secuencia de comandos gcp-build con un valor vacío en tu archivo package.json: "gcp-build":"".
  • Añade la variable de entorno de compilación GOOGLE_NODE_RUN_SCRIPTS con un valor vacío en el archivo app.yaml.

    build_env_variables:
      GOOGLE_NODE_RUN_SCRIPTS: ''
    
Para obtener información sobre cómo especificar variables de entorno de compilación, consulta la sección build_env_variables del archivo app.yaml.

Inicio de la aplicación

El tiempo de ejecución inicia la aplicación mediante npm start, que usa el comando especificado en package.json. Por ejemplo:

"scripts": {
  "start": "node app.js"
}

El script de inicio debe iniciar un servidor web que responda a las solicitudes HTTP en el puerto especificado por la variable de entorno PORT, normalmente 8080.

Prolongar el tiempo de ejecución

Puedes usar runtimes personalizados para añadir funcionalidades adicionales a una aplicación Node.js que se ejecute en el entorno flexible de App Engine. Para configurar un tiempo de ejecución personalizado, sustituye la siguiente línea en tu archivo app.yaml:

runtime: nodejs

con esta línea:

runtime: custom

También debe añadir los archivos Dockerfile y .dockerignore en el mismo directorio que el archivo app.yaml.

Consulta la documentación sobre runtimes personalizados para saber cómo definir un archivo Dockerfile en un runtime personalizado.

Proxies HTTPS y de reenvío

App Engine finaliza la conexión HTTPS en el balanceador de carga y reenvía la solicitud a tu aplicación. Algunas aplicaciones necesitan determinar la IP y el protocolo de la solicitud original. La dirección IP del usuario está disponible en la cabecera estándar X-Forwarded-For. Las aplicaciones que requieran esta información deben configurar su framework web para que confíe en el proxy.

Con Express.js, usa el ajuste trust proxy:

app.set('trust proxy', true);

Para obtener información sobre cómo aplicar conexiones HTTPS, consulta Cómo se gestionan las solicitudes.

Variables de entorno

El entorno de ejecución define las siguientes variables de entorno:

Variable de entorno Descripción
GAE_INSTANCE Nombre de la instancia actual.
GAE_MEMORY_MB Cantidad de memoria disponible para el proceso de la aplicación.
GAE_SERVICE El nombre del servicio especificado en el archivo app.yaml de tu aplicación o, si no se ha especificado ningún nombre de servicio, se define como default.
GAE_VERSION Etiqueta de versión de la aplicación actual.
GOOGLE_CLOUD_PROJECT El ID del proyecto asociado a tu aplicación, que se puede ver en la Google Cloud consola
NODE_ENV Cuando se despliega tu aplicación, el valor es production.
PORT Puerto que recibirá las solicitudes HTTP. Su valor debe ser 8080.

Puedes definir variables de entorno adicionales con app.yaml.

Servidor de metadatos

Cada instancia de tu aplicación puede usar el servidor de metadatos de Compute Engine para consultar información sobre la instancia, como su nombre de host, su dirección IP externa, su ID de instancia, sus metadatos personalizados y la información de su cuenta de servicio. App Engine no te permite definir metadatos personalizados para cada instancia, pero puedes definir metadatos personalizados para todo el proyecto y leerlos desde tus instancias de App Engine y Compute Engine.

Esta función de ejemplo usa el servidor de metadatos para obtener la dirección IP externa de la instancia.

import express from 'express';
import fetch from 'node-fetch';

const app = express();
app.enable('trust proxy');

const METADATA_NETWORK_INTERFACE_URL =
  'http://metadata/computeMetadata/v1/' +
  '/instance/network-interfaces/0/access-configs/0/external-ip';

const getExternalIp = async () => {
  const options = {
    headers: {
      'Metadata-Flavor': 'Google',
    },
    json: true,
  };

  try {
    const response = await fetch(METADATA_NETWORK_INTERFACE_URL, options);
    const ip = await response.json();
    return ip;
  } catch (err) {
    console.log('Error while talking to metadata server, assuming localhost');
    return 'localhost';
  }
};

app.get('/', async (req, res, next) => {
  try {
    const externalIp = await getExternalIp();
    res.status(200).send(`External IP: ${externalIp}`).end();
  } catch (err) {
    next(err);
  }
});

const PORT = parseInt(process.env.PORT) || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});