Il runtime Node.js

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

Versioni di Node.js

Node.js 26 (anteprima) utilizza i buildpack. Il motore Node.js predefinito utilizza la ultima release LTS. 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:

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

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

  • (Facoltativo) specifica una versione:

    • Aggiungendo l'impostazione runtime_version nel file app.yaml. Per impostazione predefinita, se l'impostazione runtime_version non è specificata, viene utilizzata l'ultima versione di Node.js. Ad esempio:

      • Per specificare Node.js 26 (anteprima) su Ubuntu 24:

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

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

        L'impostazione runtime_version supporta semver.

    • Includendo l'ultima versione di Node.js supportata nel file dell'applicazione package.json 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 che tu specifichi una versione di Node.js nel campo engines, insieme a runtime_version. Ad esempio:

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

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

Versioni runtime precedenti

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 per 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 l'ultima versione di Node.js che corrisponde all'intervallo semver. Se non viene trovata alcuna corrispondenza, il deployment dell'applicazione non riesce e il runtime restituisce un messaggio di errore.

Supporto per 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 immagini di base Docker Node.js, consulta Creazione di runtime personalizzati.

Gestore di pacchetti

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

  • Il gestore di pacchetti predefinito è npm.
  • Se nella directory principale dell'applicazione è presente un file yarn.lock, il runtime utilizza invece il gestore di pacchetti yarn.
  • Solo per Node.js versione 18 e successive, se nella directory principale dell'applicazione è presente un file pnpm-lock.yaml, il runtime utilizza invece il gestore di pacchetti Pnpm.
  • Se esistono sia un file package-lock.json sia un file yarn.lock o pnpm-lock.yaml, il deployment non riuscirà e verrà visualizzato un errore. Se hai bisogno del file package-lock.json, devi specificare gli altri file del gestore di pacchetti nella skip_files sezione del file app.yaml per risolvere il gestore di pacchetti da utilizzare.

Versione del gestore di pacchetti

L'immagine del runtime mira a utilizzare l'ultima yarn release e la release di npm disponibile nella latest release LTS di Node.js.

Puoi specificare una versione diversa del gestore di pacchetti da utilizzare nel file package.json dell'applicazione utilizzando il campo engines. In questo caso, il runtime garantisce che la versione del gestore di pacchetti utilizzata per il deployment corrisponda alla specifica elencata nel campo engines.

Se vengono fornite sia una specifica della versione di yarn sia una di npm, solo il gestore di pacchetti utilizzato per il deployment verrà aggiornato, se necessario. In questo modo si risparmia tempo di deployment perché non viene installata una versione personalizzata di un gestore di pacchetti se non viene effettivamente utilizzata per eseguire il deployment dell'applicazione.

L'esempio seguente configura il runtime per utilizzare una versione personalizzata di npm:

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

L'esempio seguente configura il runtime per 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 saperne di più su come il runtime seleziona il gestore di pacchetti da utilizzare, consulta la sezione Gestore di pacchetti.

Inoltre, per saperne di più sulla gestione dei pacchetti Node.js su Google App Engine, consulta Utilizzo delle 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 l'applicazione richiede dipendenze aggiuntive a livello di sistema operativo, dovrai utilizzare un runtime personalizzato basato su questo runtime per installare i pacchetti appropriati.

Script di build NPM

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

Per impedire l'esecuzione dello script npm run build durante la build, devi:

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

    build_env_variables:
      GOOGLE_NODE_RUN_SCRIPTS: ''
    
Per informazioni dettagliate sulla specifica delle variabili di ambiente di build, consulta la build_env_variables sezione 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 risponde alle richieste HTTP sulla porta specificata dalla variabile di ambiente PORT, in genere 8080.

Estensione del runtime

Puoi utilizzare 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 riga seguente nel file app.yaml:

runtime: nodejs

con questa riga:

runtime: custom

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

Visita la documentazione sui runtime personalizzati per scoprire come definire un Dockerfile in un runtime personalizzato.

Proxy HTTPS e di forwarding

App Engine termina la connessione HTTPS nel bilanciatore del carico e inoltra la richiesta all'applicazione. Alcune applicazioni devono determinare l'IP e il protocollo della richiesta originale. L'indirizzo IP dell'utente è disponibile nell'intestazione standard X-Forwarded-For. Le applicazioni che richiedono queste informazioni devono configurare il framework web in modo che consideri attendibile il proxy.

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

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 sono 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 il processo dell'applicazione.
GAE_SERVICE Il nome del servizio specificato nel file app.yaml dell'applicazione o, 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 all'applicazione, visibile in la Google Cloud consolle
NODE_ENV Quando l'app viene sottoposta a deployment, il valore è production.
PORT La porta che riceverà le richieste HTTP. Impostata su 8080.

Puoi impostare variabili di ambiente aggiuntive con app.yaml.

Server di metadati

Ogni istanza dell'applicazione può utilizzare il server di metadati di Compute Engine per eseguire query sulle informazioni sull'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 consente di impostare metadati personalizzati per ogni istanza, ma puoi impostare metadati personalizzati a livello di progetto e leggerli dalle istanze di App Engine e Compute Engine.

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

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.');
});