Node.js-Laufzeit

Überblick

Die Node.js-Laufzeit ist das Softwarepaket, das für die Installation Ihres Anwendungscodes und der Abhängigkeiten sowie für die Ausführung der Anwendung verantwortlich ist. Die Laufzeit wird in app.yaml als runtime: nodejs deklariert:

runtime: nodejs
env: flex

Laufzeiten in der flexiblen Umgebung werden mithilfe von Docker erstellt. Die Node.js-Laufzeit basiert auf Ubuntu 16.04. Der Quellcode für die Node.js-Laufzeit ist öffentlich auf GitHub verfügbar.

Paketmanager

Während der Bereitstellung verwendet die Laufzeit den Paketmanager "npm" oder den Paketmanager "yarn", 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.
  • Wenn package-lock.json und yarn.lock vorhanden sind, schlägt die Bereitstellung mit einem Fehler fehl. Wenn Sie beide Dateien benötigen, können Sie eine davon zum Abschnitt skip_files der Datei app.yaml hinzufügen, um anzugeben, dass der jeweils andere Paketmanager verwendet werden soll.

Engines

Node.js-Version

Die standardmäßige Node.js-Engine sollte der neueste LTS-Release sein. Sie können eine andere Node.js-Version in der Datei package.json Ihrer Anwendung über das Feld engines angeben. Sie sollten eine Node.js-Version angeben, um unerwartete Fehler zu vermeiden.

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

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

Das Attribut engines.node kann ein semver-Bereich sein. Wenn Sie dies 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 aus.

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 so konfiguriert, dass eine benutzerdefinierte Version von npm verwendet wird:

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

Im nächsten Beispiel wird die Laufzeit so konfiguriert, dass eine benutzerdefinierte Version von yarn verwendet wird:

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

Die Attribute engines.npm und engines.yarn können beide ein smerver-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.

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.

Anwendungsstart

Die Laufzeit startet Ihre Anwendung mit npm start, das den in package.json angegebenen 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

Die Node.js-Standardlaufzeit kann zum Erstellen einer benutzerdefinierten Laufzeit verwendet werden. Verwenden Sie dazu gcloud beta app gen-config --custom, um die Basisdateien Dockerfile und die .dockerignore-Dateien zu erstellen. Anschließend können Sie diese Dateien nach Bedarf anpassen. Wenn Sie Dockerfile erstellen, müssen Sie in der Datei app.yaml runtime: custom anstelle von runtime: nodejs angeben.

HTTPS und Weiterleitungsproxys

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 App 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 request = require('got');

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 {body} = await request(METADATA_NETWORK_INTERFACE_URL, options);
    return body;
  } 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 = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});