Node.js -Laufzeit

Die Node.js-Laufzeit ist das Softwarepaket, das für die Installation Ihres Anwendungscodes und der Abhängigkeiten sowie für die Ausführung dieser Anwendung in der flexiblen Umgebung verantwortlich ist.

Node.js-Versionen

Node.js 20 verwendet Buildpacks. Die standardmäßige Node.js-Engine verwendet den neuesten LTS-Release. Eine vollständige Liste der unterstützten Node.js-Versionen und der entsprechenden Ubuntu-Versionen finden Sie im Laufzeitsupportzeitplan.

So verwenden Sie eine unterstützte Node.js-Version:

  • Installieren Sie die gcloud CLI-Version 420.0.0 oder höher. Sie können die Befehlszeilentools mit dem Befehl gcloud components update aktualisieren. Führen Sie den Befehl gcloud version aus, um Ihre installierte Version aufzurufen.

  • Fügen Sie die Einstellungen runtime_config und operating_system in die Datei app.yaml ein, um ein Betriebssystem anzugeben.

  • Sie können optional eine Version angeben, indem Sie:

    • Die Einstellung runtime_version in die Datei app.yaml einfügen. Standardmäßig wird die neueste Node.js-Version verwendet, wenn die Einstellung runtime_version nicht angegeben ist. Beispiel:

      • So geben Sie Node.js 20 auf Ubuntu 22 an:

          runtime: nodejs
          env: flex
        
          runtime_config:
              operating_system: "ubuntu22"
              runtime_version: "20"
        
      • Neueste unterstützte Node.js-Version unter Ubuntu 22 angeben:

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

        Die Einstellung runtime_version unterstützt semver.

    • Fügen Sie die neueste unterstützte Node.js-Version in der Datei package.json Ihrer Anwendung mithilfe des Felds engines ein. Wenn Sie im Feld engines eine Version angeben, hat die Einstellung runtime_version Vorrang. Um unerwartete Fehler zu vermeiden, empfehlen wir, im Feld engines eine Node.js-Version sowie das runtime_version anzugeben. Beispiel:

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

      Das Attribut engines.node kann ein semver-Bereich sein. Wenn Sie diese Eigenschaft angeben, lädt die Laufzeit die neueste Version von Node.js herunter, die dem semver-Bereich entspricht, und installiert sie. Wenn keine Übereinstimmung gefunden wird, kann die Anwendung nicht bereitgestellt werden und die Laufzeit gibt einen Fehler zurück.

Vorherige Laufzeitversionen

Geben Sie für die Node.js-Laufzeit Version 16 und früher eine Version in der Datei package.json Ihrer Anwendung mit dem Feld engines an.

Im folgenden Beispiel wird die Laufzeit konfiguriert, um den Release Node 9 zu verwenden.

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

Das Attribut engines.node kann ein semver-Bereich sein. Wenn Sie diese Eigenschaft angeben, lädt die Laufzeit die neueste Version von Node.js herunter, die dem semver-Bereich entspricht, und installiert sie. Wenn keine Übereinstimmung gefunden wird, kann die Anwendung nicht bereitgestellt werden und die Laufzeit gibt eine Fehlermeldung zurück.

Unterstützung für andere Node.js-Laufzeiten

Wenn Sie eine Node.js-Version verwenden müssen, die nicht unterstützt wird, können Sie eine benutzerdefinierte Laufzeit erstellen und ein gültiges Basis-Image mit der von Ihnen benötigten Node.js-Version auswählen.

Informationen zu von Google bereitgestellten Basis-Images oder Docker-Basis-Images für Node.js finden Sie unter Benutzerdefinierte Laufzeiten erstellen.

Paketmanager

Während der Bereitstellung verwendet die Laufzeit die npm oder "yarn" oder Pnpm, um Abhängigkeiten zu installieren und die Anwendung zu starten. Der Paketmanager wird mit der folgenden Logik festgelegt:

  • Der Standardpaketmanager ist npm.
  • Wenn sich eine yarn.lock-Datei im Stammverzeichnis Ihrer Anwendung befindet, verwendet die Laufzeit stattdessen den Paketmanager yarn.
  • Nur für Node.js-Version 18 und höher verwendet die Laufzeit stattdessen den Pnpm-Paketmanager, wenn sich die Datei pnpm-lock.yaml im Stammverzeichnis Ihrer Anwendung befindet.
  • Wenn package-lock.json und yarn.lock oder pnpm-lock.yaml vorhanden sind, schlägt die Bereitstellung mit einem Fehler fehl. Wenn Sie die package-lock.json Datei benötigen, müssen Sie die anderen Paketmanagerdateien im Abschnitt skip_files Ihrer app.yaml Datei angeben, um zu ermitteln, welcher Paketmanager verwendet werden soll.

Version des Paketmanagers

Das Laufzeit-Image sollte den neuesten yarn-Release verwenden und den Release von npm, der im neuesten Node.js-LTS-Release verfügbar ist.

Sie können in der Datei package.json der Anwendung mithilfe des Felds engines eine andere Paketmanagerversion angeben, die verwendet werden soll. In diesem Fall sorgt die Laufzeit dafür, dass der für die Bereitstellung verwendete Paketmanager in der Version verwendet wird, die der im Feld engines aufgeführten Spezifikation entspricht.

Wenn sowohl eine yarn- als auch eine npm-Versionsspezifikation angegeben ist, wird bei Bedarf nur der für die Bereitstellung verwendete Paketmanager aktualisiert. Dies spart Installationszeit, da keine benutzerdefinierte Version eines Paketmanagers installiert wird, die nicht tatsächlich zum Bereitstellen der Anwendung verwendet wird.

Im folgenden Beispiel wird die Laufzeit dafür konfiguriert, eine benutzerdefinierte Version von npm zu verwenden:

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

Im nächsten Beispiel wird die Laufzeit dafür konfiguriert, eine benutzerdefinierte Version von yarn zu verwenden:

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

Die Attribute engines.npm und engines.yarn können jeweils ein semver-Bereich sein.

Abhängigkeiten

Während der Bereitstellung verwendet die Laufzeit entweder den Paketmanager npm oder den yarn-Paketmanager, um Abhängigkeiten durch Ausführung von npm install oder yarn install zu installieren. Weitere Informationen dazu, wie die Laufzeit den Paketmanager auswählt, der verwendet werden soll, finden Sie im Abschnitt Paketmanager.

Weitere Informationen zum Verwalten von Node.js-Paketen in Google App Engine finden Sie unter Node.js-Bibliotheken verwenden.

Damit Node.js-Pakete verwendet werden können, die native Erweiterungen erfordern, sind die folgenden Ubuntu-Pakete im Docker-Image vorinstalliert.

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

Wenn Ihre Anwendung zusätzliche Abhängigkeiten auf Betriebssystemebene erfordert, müssen Sie eine auf dieser Laufzeit basierende benutzerdefinierte Laufzeit verwenden, um die entsprechenden Pakete zu installieren.

NPM-Build-Skript

Für die Node.js-Laufzeit Version 18 und höher führt die Laufzeitumgebung npm run build aus, wenn standardmäßig ein build-Skript in package.json erkannt wird. Wenn Sie vor dem Starten Ihrer Anwendung zusätzliche Kontrolle über die Build-Schritte benötigen, können Sie einen benutzerdefinierten Build-Schritt hinzufügen. Fügen Sie dazu der Datei package.json ein gcp-build-Skript hinzu.

Wenn Sie verhindern möchten, dass Ihr Build das Script npm run build ausführt, haben Sie folgende Möglichkeiten:

  • Fügen Sie ein gcp-build-Script mit einem leeren Wert in Ihre package.json-Datei ein: "gcp-build":"".
  • Fügen Sie die Build-Umgebungsvariable GOOGLE_NODE_RUN_SCRIPTS mit einem leeren Wert in die Datei app.yaml ein.

    build_env_variables:
      GOOGLE_NODE_RUN_SCRIPTS: ''
    
Weitere Informationen zum Angeben von Build-Umgebungsvariablen finden Sie in der Datei app.yaml im Abschnitt build_env_variables.

Anwendungsstart

Die Laufzeit startet Ihre Anwendung mit npm start. Dabei wird der in package.json angegebene Befehl verwendet. Beispiel:

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

Durch das Startskript sollte ein Webserver gestartet werden, der auf HTTP-Anfragen am durch die Umgebungsvariable PORT angegebenen Port antwortet, in der Regel Port 8080.

Laufzeit erweitern

Mit benutzerdefinierten Laufzeiten können Sie einer Node.js-Anwendung, die in der flexiblen App Engine-Umgebung ausgeführt wird, zusätzliche Funktionen hinzufügen. Zum Konfigurieren einer benutzerdefinierten Laufzeit ersetzen Sie die folgende Zeile in der Datei app.yaml:

runtime: nodejs

durch diese Zeile:

runtime: custom

Fügen Sie außerdem die Dateien Dockerfile und .dockerignore in das Verzeichnis ein, das die Datei app.yaml enthält.

Informationen zum Definieren eines Dockerfiles in einer benutzerdefinierten Laufzeit finden Sie in der Dokumentation zu benutzerdefinierten Laufzeiten.

HTTPS- und Weiterleitungs-Proxys

App Engine beendet die HTTPS-Verbindung am Load-Balancer und leitet die Anfrage zu Ihrer Anwendung weiter. Einige Anwendungen müssen die ursprüngliche Request-IP-Adresse und das Protokoll bestimmen. Die IP-Adresse des Nutzers ist im Standardheader X-Forwarded-For verfügbar. Bei Anwendungen, die diese Informationen erfordern, sollte das Web-Framework so konfiguriert werden, dass dem Proxy vertraut wird.

Verwenden Sie für Express.js die Einstellung trust proxy:

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

Informationen zum Erzwingen von HTTPS-Verbindungen finden Sie unter Anfrageverarbeitung.

Umgebungsvariablen

Die folgenden Umgebungsvariablen werden durch die Laufzeitumgebung festgelegt:

Umgebungsvariable Beschreibung
GAE_INSTANCE Der Name der aktuellen Instanz
GAE_MEMORY_MB Die Größe des für den Anwendungsprozess verfügbaren Speichers
GAE_SERVICE Der in der Datei app.yaml Ihrer Anwendung angegebene Dienstname. Wenn kein Dienstname angegeben ist, wird als Wert default festgelegt.
GAE_VERSION Das Versionslabel der aktuellen Anwendung
GOOGLE_CLOUD_PROJECT Die mit Ihrer Anwendung verknüpfte Projekt-ID, die in der Google Cloud Console angezeigt wird
NODE_ENV Wenn Ihre Anwendung bereitgestellt wird, lautet der Wert production.
PORT Der Port, der HTTP-Anfragen empfängt Legen Sie 8080 fest.

Sie können mit app.yaml noch weitere Umgebungsvariablen festlegen.

Metadatenserver

Jede Instanz der Anwendung kann den Compute Engine-Metadatenserver verwenden, um Informationen über die Instanz abzufragen, einschließlich Hostname, externer IP-Adresse, Instanz-ID, benutzerdefinierter Metadaten und Dienstkontoinformationen. Sie können in App Engine nicht für jede einzelne Instanz benutzerdefinierte Metadaten festlegen. Sie haben aber die Möglichkeit, projektweite benutzerdefinierte Metadaten anzugeben und aus den App Engine- und Compute Engine-Instanzen zu lesen.

Diese Beispielfunktion ruft die externe IP-Adresse der Instanz über den Metadatenserver ab.

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