Il runtime Node.js

Il runtime Node.js è lo stack software responsabile dell'installazione del codice e delle dipendenze dell'applicazione, nonché dell'esecuzione dell'applicazione nell'ambiente flessibile.

Versioni di Node.js

Node.js 22 utilizza buildpacks. Il motore Node.js predefinito utilizza la release LTS più recente. Per l'elenco completo delle versioni di Node.js supportate e della versione di Ubuntu corrispondente, consulta la pianificazione del supporto del runtime.

Per utilizzare una versione di Node.js supportata, devi:

  • Installa gcloud CLI versione 420.0.0 o successive. Puoi aggiornare gli strumenti CLI eseguendo il comando gcloud components update. Per visualizzare la versione installata, esegui il comando gcloud version.

  • Includi le impostazioni runtime_config e operating_system nel app.yaml per specificare un sistema operativo.

  • (Facoltativo) Specifica una versione:

    • Aggiunta dell'impostazione runtime_version nel file app.yaml. Per impostazione predefinita, viene utilizzata la versione più recente di Node.js se non viene specificata l'impostazione runtime_version. Ad esempio:

      • Per specificare Node.js 22 su Ubuntu 22:

          runtime: nodejs
          env: flex
        
          runtime_config:
              operating_system: "ubuntu22"
              runtime_version: "22"
        
      • Per specificare l'ultima versione di Node.js supportata su Ubuntu 22:

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

        L'impostazione runtime_version supporta semver.

    • Includi la versione più recente di Node.js supportata nel file package.json dell'applicazione utilizzando il campo engines. Quando utilizzi il campo engines per specificare una versione, l'impostazione runtime_version ha la precedenza. Per evitare interruzioni impreviste, ti consigliamo di specificare una versione di Node.js nel campo engines, insieme a runtime_version. Ad esempio:

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

      La proprietà engines.node può essere un intervallo semver. Se specifichi questa proprietà, il runtime scarica e installa la versione più recente di Node.js corrispondente all'intervallo semver. Se non viene trovata alcuna corrispondenza, il deployment dell'applicazione non riesce e il runtime restituisce un errore.

Versioni precedenti dell'ambiente di runtime

Per il runtime Node.js versione 16 e precedenti, specifica una versione nel file package.json dell'applicazione utilizzando il campo engines.

L'esempio seguente configura il runtime in modo da utilizzare la release Node 9:

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

La proprietà engines.node può essere un intervallo semver. Se specifichi questa proprietà, il runtime scarica e installa la versione più recente di Node.js corrispondente all'intervallo semver. Se non viene trovata alcuna corrispondenza, il deployment dell'applicazione non riesce e il runtime restituisce un messaggio di errore.

Supporto di altri runtime Node.js

Se devi utilizzare una versione di Node.js non supportata, puoi creare un runtime personalizzato e selezionare un'immagine di base valida con la versione di Node.js di cui hai bisogno.

Per le immagini di base fornite da Google o per le immagini di base Docker Node.js, consulta Creare runtime personalizzati.

Gestore pacchetti

Durante il deployment, il runtime utilizza il gestore di pacchetti npm, yarn o Pnpm per installare le dipendenze e avviare l'applicazione. Il package manager viene impostato con la seguente logica:

  • Il gestore pacchetti predefinito è npm.
  • Se nella directory principale della tua applicazione è presente un file yarn.lock, il runtime utilizza il gestore pacchetti yarn.
  • Solo per Node.js versione 18 e successive, se nella directory principale della tua applicazione è presente un file pnpm-lock.yaml, il runtime utilizza il gestore dei pacchetti Pnpm.
  • Se esistono sia package-lock.json sia yarn.lock o pnpm-lock.yaml, il deployment non andrà a buon fine e verrà visualizzato un errore. Se hai bisogno del file package-lock.json, devi specificare gli altri file del gestore dei pacchetti nella sezione skip_files del file app.yaml per risolvere quale gestire i pacchetti da utilizzare.

Versione del gestore dei pacchetti

L'immagine di runtime ha come obiettivo l'utilizzo dell'ultima release di yarn e della release di npm disponibile nell'ultima release LTS di Node.js.

Puoi specificare una versione diversa del gestore pacchetti da utilizzare nel file package.json della tua applicazione utilizzando il campo engines. In questo caso, il runtime garantisce che il gestore dei pacchetti utilizzato per il deployment abbia una versione corrispondente alla specifica elencata nel campo engines.

Se vengono specificate sia la versione yarn sia la versione npm, verrà aggiornato solo il gestore pacchetti utilizzato per il deployment, se necessario. In questo modo risparmi tempo di implementazione perché non viene installata una versione personalizzata di un gestore di pacchetti se non viene effettivamente utilizzata per implementare l'applicazione.

L'esempio seguente configura il runtime in modo da utilizzare una versione personalizzata di npm:

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

L'esempio seguente configura l'ambiente di runtime in modo da utilizzare una versione personalizzata di yarn:

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

Le proprietà engines.npm e engines.yarn possono essere entrambe un intervallo semver.

Dipendenze

Durante il deployment, il runtime utilizzerà il gestore di pacchetti npm o yarn per installare le dipendenze eseguendo npm install o yarn install. Per ulteriori informazioni su come il runtime seleziona il gestore pacchetti da utilizzare, consulta la sezione Gestore pacchetti.

Inoltre, per saperne di più sulla gestione dei pacchetti Node.js su Google App Engine, consulta Utilizzare le librerie Node.js.

Per consentire l'utilizzo dei pacchetti Node.js che richiedono estensioni native, i seguenti pacchetti Ubuntu sono preinstallati nell'immagine Docker.

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

Se la tua applicazione richiede dipendenze aggiuntive a livello di sistema operativo, devi utilizzare un runtime personalizzato basato su questo runtime per installare i pacchetti appropriati.

Script di build NPM

Per il runtime di Node.js versione 18 e successive, l'ambiente di runtime esegue npm run build se per impostazione predefinita viene rilevato uno script build in package.json. Se hai bisogno di un maggiore controllo sui passaggi di compilazione prima di avviare l'applicazione, puoi fornire un passaggio di compilazione personalizzato aggiungendo uno script gcp-build al file package.json.

Per impedire alla build di eseguire lo script npm run build, devi:

  • Aggiungi uno script gcp-build con un valore vuoto nel file package.json: "gcp-build":"".
  • Aggiungi la variabile di ambiente di compilazione GOOGLE_NODE_RUN_SCRIPTS con un valore vuoto nel file app.yaml.

    build_env_variables:
      GOOGLE_NODE_RUN_SCRIPTS: ''
    
Per informazioni dettagliate su come specificare le variabili di ambiente di compilazione, consulta la sezione build_env_variables nel file app.yaml.

Avvio dell'applicazione

Il runtime avvia l'applicazione utilizzando npm start, che utilizza il comando specificato in package.json. Ad esempio:

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

Lo script di avvio deve avviare un server web che risponda alle richieste HTTP sulla porta specificata dalla variabile di ambiente PORT, in genere 8080.

Estensione del runtime

Puoi utilizzare i runtime personalizzati per aggiungere funzionalità aggiuntive a un'app Node.js in esecuzione nell'ambiente flessibile di App Engine. Per configurare un runtime personalizzato, sostituisci la seguente riga nel file app.yaml:

runtime: nodejs

con questa riga:

runtime: custom

Devi anche aggiungere i file Dockerfile e .dockerignore nella stessa directory che contiene il file app.yaml.

Consulta la documentazione relativa ai runtime personalizzati per scoprire come definire un Dockerfile in un runtime personalizzato.

Proxy HTTPS e di inoltro

App Engine termina la connessione HTTPS al bilanciatore del carico e inoltra la richiesta alla tua applicazione. Alcune applicazioni devono determinare l'IP e il protocollo della richiesta originale. L'indirizzo IP dell'utente è disponibile nell'intestazioneX-Forwarded-For standard. Le applicazioni che richiedono queste informazioni devono configurare il proprio framework web in modo che attenda il proxy.

Con Express.js, utilizza l'impostazione trust proxy:

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

Per informazioni sull'applicazione delle connessioni HTTPS, consulta Come vengono gestite le richieste.

Variabili di ambiente

Le seguenti variabili di ambiente vengono impostate dall'ambiente di runtime:

Variabile di ambiente Descrizione
GAE_INSTANCE Il nome dell'istanza corrente.
GAE_MEMORY_MB La quantità di memoria disponibile per la procedura di richiesta.
GAE_SERVICE Il nome del servizio specificato nel file app.yaml dell'applicazione oppure, se non è specificato alcun nome del servizio, viene impostato su default.
GAE_VERSION L'etichetta della versione dell'applicazione corrente.
GOOGLE_CLOUD_PROJECT L'ID progetto associato alla tua applicazione, visibile nella console Google Cloud
NODE_ENV Quando l'app viene dispiata, il valore è production.
PORT La porta che riceverà le richieste HTTP. Imposta su 8080.

Puoi impostare variabili di ambiente aggiuntive con app.yaml.

Server dei metadati

Ogni istanza della tua applicazione può utilizzare il server metadati di Compute Engine per eseguire query sulle informazioni dell'istanza, inclusi il nome host, l'indirizzo IP esterno, l'ID istanza, i metadati personalizzati e le informazioni sull'account di servizio. App Engine non ti consente di impostare metadati personalizzati per ogni istanza, ma puoi impostare metadati personalizzati a livello di progetto e leggerli dalle istanze App Engine e Compute Engine.

Questa funzione di esempio utilizza il server di metadati per recuperare l'indirizzo IP esterno dell'istanza.

const express = require('express');
const fetch = require('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.');
});