Konfigurieren einer Node.js-App für Azure App Service

Node.js-Apps müssen mit allen erforderlichen npm-Abhängigkeiten bereitgestellt werden. Die App Service-Bereitstellungs-Engine führt automatisch npm install --production für Sie aus, wenn Sie ein Git-Repository oder ein ZIP-Paket mit aktivierter Buildautomatisierung bereitstellen. Wenn Sie Ihre Dateien jedoch mit FTP/S bereitstellen, müssen Sie die erforderlichen Pakete manuell hochladen.

Diese Anleitung enthält die wichtigsten Konzepte und Anweisungen für Node.js-Entwickler, die in App Service bereitstellen. Wenn Sie Azure App Service noch nie verwendet haben, befolgen Sie zunächst den Node.js-Schnellstart und das Tutorial Node.js mit dem MongoDB.

Anzeigen der Node.js-Version

Führen Sie in Cloud Shell den folgenden Befehl aus, um die aktuelle Node.js-Version anzuzeigen:

az webapp config appsettings list --name <app-name> --resource-group <resource-group-name> --query "[?name=='WEBSITE_NODE_DEFAULT_VERSION'].value"

Um alle unterstützten Node.js-Versionen anzuzeigen, navigieren Sie zu https://<sitename>.scm.azurewebsites.net/api/diagnostics/runtime, oder führen Sie den folgenden Befehl in der https://<sitename>.scm.azurewebsites.net/api/diagnostics/runtime aus.

az webapp list-runtimes --os windows | grep NODE

Führen Sie in Cloud Shell den folgenden Befehl aus, um die aktuelle Node.js-Version anzuzeigen:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

Führen Sie in Cloud Shell den folgenden Befehl aus, um alle unterstützten Node.js-Versionen anzuzeigen:

az webapp list-runtimes --os linux | grep NODE

Festlegen der Node.js-Version

Führen Sie in Cloud Shell den folgenden Befehl aus, um WEBSITE_NODE_DEFAULT_VERSION auf eine unterstützte Version und für Ihre App eine unterstützte Node.js-Version festzulegen:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_NODE_DEFAULT_VERSION="~16"

Hinweis

In diesem Beispiel wird die empfohlene Tildensyntax verwendet, um die neueste verfügbare Version der Node.js 16-Runtime für App Service zu verwenden.

Da die Runtime regelmäßig von der Plattform gepatcht und aktualisiert wird, sollte eine Einschränkung auf bestimmte Nebenversionen/Patches vermieden werden, da deren Verfügbarkeit aufgrund potenzieller Sicherheitsrisiken nicht garantiert ist.

Hinweis

Sie sollten die Node.js-Version in der package.json des Projekts festlegen. Die Bereitstellungs-Engine wird in einem separaten Prozess ausgeführt, der alle unterstützten Node.js-Versionen enthält.

Führen Sie in Cloud Shell den folgenden Befehl aus, um für Ihre App eine unterstützte Node.js-Version festzulegen:

az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "NODE|14-lts"

Diese Einstellung legt die zu verwendende Version von Node.js fest, sowohl zur Laufzeit als auch während der automatischen Paketwiederherstellung in Kudu.

Hinweis

Sie sollten die Node.js-Version in der package.json des Projekts festlegen. Die Bereitstellungs-Engine wird in einem separaten Container ausgeführt, der alle unterstützten Node.js-Versionen enthält.

Abrufen der Portnummer

Ihre Node.js-App muss am richtigen Port lauschen, um eingehende Anforderungen empfangen zu können.

In App Service unter Windows werden Node.js-Apps mit IISNode gehostet, und Ihre Node.js-App sollte an dem Port lauschen, der in der Variablen process.env.PORT angegeben ist. Im folgenden Beispiel wird veranschaulicht, wie Sie hierbei für eine einfache Express-App vorgehen:

App Service legt die Umgebungsvariable PORT im Node.js-Container fest und leitet die eingehenden Anforderungen unter dieser Portnummer an Ihren Container weiter. Um die Anforderungen erhalten zu können, sollte Ihre App mit process.env.PORT an diesem Port lauschen. Im folgenden Beispiel wird veranschaulicht, wie Sie hierbei für eine einfache Express-App vorgehen:

const express = require('express')
const app = express()
const port = process.env.PORT || 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

Anpassen der Buildautomatisierung

Wenn Sie Ihre App mithilfe von Git oder mit ZIP-Paketen mit aktivierter Buildautomatisierung bereitstellen, durchläuft die App Service-Buildautomatisierung die Schritte der folgenden Sequenz:

  1. Führen Sie benutzerdefinierte Skripts aus, wenn sie durch PRE_BUILD_SCRIPT_PATH angegeben werden.
  2. Ausführen von npm install ohne Flags, was npm preinstall und postinstall-Skripts einschließt und auch devDependencies installiert.
  3. Ausführen von npm run build, wenn ein Buildskript in Ihrer npm run build angegeben ist.
  4. Ausführen von npm run build:azure, wenn ein build:azure-Skript in Ihrer npm run build:azure angegeben ist.
  5. Ausführen eines benutzerdefinierten Skripts, falls mittels POST_BUILD_SCRIPT_PATH angegeben.

Hinweis

Wie in der npm-Dokumentation beschrieben, werden Skripts namens prebuild und postbuild (sofern angegeben) vor bzw. nach build ausgeführt. preinstall und postinstall werden vor bzw. nach install ausgeführt.

PRE_BUILD_COMMAND und POST_BUILD_COMMAND sind Umgebungsvariablen, die standardmäßig leer sind. Um Präbuildbefehle auszuführen, definieren Sie PRE_BUILD_COMMAND. Um Postbuildbefehle auszuführen, definieren Sie POST_BUILD_COMMAND.

Im folgenden Beispiel werden die beiden Variablen für mehrere Befehle angegeben (mit Kommas als Trennzeichen).

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PRE_BUILD_COMMAND="echo foo, scripts/prebuild.sh"
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings POST_BUILD_COMMAND="echo foo, scripts/postbuild.sh"

Weitere Informationen zu zusätzlichen Umgebungsvariablen für das Anpassen der Buildautomatisierung finden Sie unter Oryx-Konfiguration.

Weitere Informationen, wie App Service Node.js-Apps in Linux ausführt und erstellt, finden Sie unter Oryx-Dokumentation: Erkennen und Erstellen von Node.js-Apps.

Konfigurieren des Node.js-Servers

Die Node.js-Container werden mit PM2, einem Manager für den Produktionsprozess, ausgeliefert. Sie können Ihre App so konfigurieren, dass sie mit PM2, mit npm oder mit einem benutzerdefinierten Befehl startet.

Tool Zweck
Mit PM2 ausführen Empfohlen: Verwendung in der Produktion oder im Stagingprozess PM2 bietet eine Full-Service-App-Verwaltungsplattform.
Ausführen mit npm-Start Nur für Entwicklungszwecke.
Ausführen mit einem benutzerdefinierten Befehl Entweder Entwicklung oder Staging.

Mit PM2 ausführen

Der Container startet Ihre App automatisch mit PM2, wenn sich eine der üblichen Node.js-Dateien in Ihrem Projekt befindet:

  • bin/www
  • server.js
  • app.js
  • index.js
  • hostingstart.js
  • Eine der folgenden PM2-Dateien: process.json oder ecosystem.config.js

Sie können auch eine benutzerdefinierte Startdatei mit den folgenden Erweiterungen konfigurieren:

  • Eine .js-Datei
  • Eine PM2-Datei mit der Erweiterung .json, .config.js, .yaml oder .yml.

Hinweis

Ab Node 14 LTS startet der Container Ihre App nicht automatisch mit PM2. Um Ihre App mit PM2 zu starten, legen Sie den Startbefehl auf pm2 start <.js-file-or-PM2-file> --no-daemon fest. Achten Sie darauf, das --no-daemon-Argument zu verwenden, da PM2 im Vordergrund ausgeführt werden muss, damit der Container ordnungsgemäß funktioniert.

Führen Sie zum Hinzufügen einer benutzerdefinierten Startdatei den folgenden Befehl in der Cloud Shell aus:

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<filename-with-extension>"

Ausführen mit einem benutzerdefinierten Befehl

App Service kann Ihre App mit einem benutzerdefinierten Befehl starten (z. B. mit einer ausführbaren Datei wie run.sh. Führen Sie beispielsweise zum Ausführen von npm run start:prod den folgenden Befehl in Cloud Shell aus:

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "npm run start:prod"

Ausführen mit npm-Start

Um Ihre App mit npm start zu starten, stellen Sie einfach sicher, dass sich ein start-Skript in der Datei npm start befindet. Beispiel:

{
  ...
  "scripts": {
    "start": "gulp",
    ...
  },
  ...
}

Führen Sie den folgenden Befehl in der Cloud Shell aus, um eine benutzerdefinierte package.json-Datei in Ihrem Projekt zu verwenden:

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<filename>.json"

Remote Debuggen

Sie können Ihre Node.js-App remote in Visual Studio Code debuggen, wenn Sie sie so konfigurieren, dass sie mit PM2 ausgeführt wird, außer Sie führen sie mit einer Datei vom Typ „.config.js“, „.yml“ oder „.yaml“ aus.

In den meisten Fällen ist keine zusätzliche Konfiguration für Ihre App erforderlich. Wenn Ihre App mit einer process.json-Datei (Standard oder benutzerdefiniert) ausgeführt wird, muss sie über eine script-Eigenschaft im JSON-Stammverzeichnis verfügen. Beispiel:

{
  "name"        : "worker",
  "script"      : "./index.js",
  ...
}

Um Visual Studio Code für das Remotedebuggen einzurichten, installieren Sie die App Service-Erweiterung. Folgen Sie den Anweisungen auf der Erweiterungsseite, und melden Sie sich in Visual Studio Code bei Azure an.

Suchen Sie im Azure Explorer die App, die Sie debuggen möchten, klicken Sie mit der rechten Maustaste darauf, und wählen Sie Remotedebuggen starten aus. Wählen Sie Ja aus, um das Remotedebugging für Ihre App zu aktivieren. App Service startet für Sie einen Tunnelproxy und fügt den Debugger an. Sie können dann Anforderungen an die App stellen und sehen, wie der Debugger an Haltepunkten anhält.

Nachdem Sie mit dem Debuggen fertig sind, stoppen Sie den Debugger, indem Sie Trennen auswählen. Wenn Sie dazu aufgefordert werden, wählen Sie Ja aus, um das Remotedebuggen zu deaktivieren. Um es später zu deaktivieren, klicken Sie mit der rechten Maustaste erneut auf Ihre App im Azure Explorer, und wählen Sie Remotedebuggen deaktivieren aus.

Zugreifen auf Umgebungsvariablen

In App Service können Sie App-Einstellungen außerhalb Ihres App-Codes festlegen. Anschließend können Sie darauf unter Verwendung des Node.js-Standardmusters zugreifen. Verwenden Sie beispielsweise den folgenden Code, um auf eine App-Einstellung namens NODE_ENV zuzugreifen:

process.env.NODE_ENV

Run Grunt/Bower/Gulp

Standardmäßig führt die App Service-Buildautomatisierung npm install --production aus, wenn sie erkennt, dass eine Node.js-App über Git oder mit einer ZIP-Bereitstellung mit aktivierter Buildautomatisierung bereitgestellt wird. Wenn Ihre App eines der beliebten Automationstools wie Grunt, Bower oder Gulp benötigt, müssen Sie ein benutzerdefiniertes Bereitstellungsskript bereitstellen, um es auszuführen.

Damit Ihr Repository diese Tools ausführen kann, müssen Sie sie zu den Abhängigkeiten in package.json hinzufügen. Beispiel:

"dependencies": {
  "bower": "^1.7.9",
  "grunt": "^1.0.1",
  "gulp": "^3.9.1",
  ...
}

Wechseln Sie von einem lokalen Terminalfenster aus in das Stammverzeichnis Ihres Repositorys, und führen Sie die folgenden Befehle aus:

npm install kuduscript -g
kuduscript --node --scriptType bash --suppressPrompt

Das Stammverzeichnis Ihres Repositorys enthält jetzt zwei zusätzliche Dateien: .deployment und deploy.sh.

Öffnen Sie deploy.sh und suchen Sie den Abschnitt Deployment, der wie folgt aussieht:

##################################################################################################################################
# Deployment
# ----------

Dieser Abschnitt endet mit dem Ausführen von npm install --production. Fügen Sie den Codeabschnitt, den Sie zum Ausführen des erforderlichen Tools benötigen, am Ende des Abschnitts Deployment hinzu:

Weitere Informationen finden Sie in einem Beispiel im der MEAN.js-Beispiel, in dem das Bereitstellungsskript auch einen benutzerdefinierten npm install-Befehl ausführt.

Bower

Dieser Codeausschnitt führt bower install aus.

if [ -e "$DEPLOYMENT_TARGET/bower.json" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/bower install
  exitWithMessageOnError "bower failed"
  cd - > /dev/null
fi

Gulp

Dieser Codeausschnitt führt gulp imagemin aus.

if [ -e "$DEPLOYMENT_TARGET/gulpfile.js" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/gulp imagemin
  exitWithMessageOnError "gulp failed"
  cd - > /dev/null
fi

Grunt

Dieser Codeausschnitt führt grunt aus.

if [ -e "$DEPLOYMENT_TARGET/Gruntfile.js" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/grunt
  exitWithMessageOnError "Grunt failed"
  cd - > /dev/null
fi

Erkennen einer HTTPS-Sitzung

In App Service erfolgt die TLS/SSL-Terminierung in den Modulen für den Netzwerklastenausgleich, sodass alle HTTPS-Anforderungen Ihre App als unverschlüsselte HTTP-Anforderungen erreichen. Wenn Ihre App-Logik überprüfen muss, ob Benutzeranforderungen verschlüsselt sind, überprüfen Sie dazu den X-Forwarded-Proto-Header.

Gängige Webframeworks ermöglichen den Zugriff auf die Information X-Forwarded-* in Ihrem App-Standardmuster. In Express können Sie trust proxies (Proxys vertrauen) verwenden. Beispiel:

app.set('trust proxy', 1)
...
if (req.secure) {
  // Do something when HTTPS is used
}

Zugreifen auf Diagnoseprotokolle

Aktivieren Sie die Diagnoseprotokollierung, indem Sie den folgenden Befehl in Cloud Shellausführen, um auf die Konsolenprotokolle zuzugreifen, die innerhalb des Anwendungscodes in App Service generiert wurden:

az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose

Mögliche Werte für --level sind Error, WarningInfo oder Verbose. Jede nachfolgende Ebene enthält die vorherige Ebene. Beispiel: Error enthält nur Fehlermeldungen, und Verbose enthält alle Meldungen.

Führen Sie den folgenden Befehl aus, um den Protokolldatenstrom anzuzeigen, nachdem die Diagnoseprotokollierung aktiviert wurde:

az webapp log tail --resource-group <resource-group-name> --name <app-name>

Falls Sie nicht sofort Konsolenprotokolle sehen, können Sie es nach 30 Sekunden noch einmal versuchen.

Hinweis

Sie können die Protokolldateien auch im Browser unter https://<app-name>.scm.azurewebsites.net/api/logs/docker untersuchen.

Um das Protokollstreaming jederzeit zu beenden, geben Sie Ctrl+C ein.

Sie können auf die Konsolenprotokolle zugreifen, die aus dem Container generiert werden.

Aktivieren Sie zuerst Containerprotokollierung, indem Sie den folgenden Befehl ausführen:

az webapp log config --name <app-name> --resource-group <resource-group-name> --docker-container-logging filesystem

Ersetzen Sie <app-name> und <resource-group-name> durch die entsprechenden Namen für Ihre Web-App.

Führen Sie den folgenden Befehl aus, um den Protokolldatenstrom anzuzeigen, nachdem die Containerprotokollierung aktiviert wurde:

az webapp log tail --name <app-name> --resource-group <resource-group-name>

Falls Sie nicht sofort Konsolenprotokolle sehen, können Sie es nach 30 Sekunden noch einmal versuchen.

Zum Beenden des Protokollstreamings können Sie jederzeit STRG+C drücken.

Sie können die Protokolldateien auch in einem Browser unter https://<app-name>.scm.azurewebsites.net/api/logs/docker untersuchen.

URL-Umschreibungen

Bei der Bereitstellung von Node.js-Apps in Azure App Service für Linux müssen Sie möglicherweise URL-Umschreibungen direkt innerhalb Ihrer Anwendung behandeln. Dies ist besonders hilfreich, um sicherzustellen, dass bestimmte URL-Muster an die richtigen Endpunkte umgeleitet werden, ohne sich auf Webserverkonfigurationen zu verlassen. Es gibt verschiedene Möglichkeiten zum Ausführen von URL-Umschreibungen in Node.js. Ein Beispiel hierfür ist das express-urlrewrite-Paket.

Überwachen mit Application Insights

Mit Application Insights können Sie die Leistung, die Ausnahmen und die Verwendung Ihrer Anwendung überwachen, ohne Codeänderungen vorzunehmen. Um den Application Insights-Agent anzufügen, navigieren Sie im Portal zu Ihrer Web-App, und wählen Sie unter Einstellungen die Option Application Insights und dann Application Insights aktivieren aus. Wählen Sie dann eine vorhandene Application Insights-Ressource aus, oder erstellen Sie eine neue Ressource. Klicken Sie abschließend unten auf Anwenden. Weitere Informationen zum Instrumentieren der Web-App mit PowerShell finden Sie in diesen Anweisungen.

Mit diesem Agent wird die serverseitige Node.js-Anwendung überwacht. Um clientseitiges JavaScript zu überwachen, fügen Sie dem Projekt das JavaScript SDK hinzu.

Weitere Informationen finden Sie in den Versionshinweisen für die Erweiterung für Azure-Web-Apps für Application Insights.

Problembehandlung

Wenn sich eine funktionierende Node.js-App in App Service anders verhält oder Fehler aufweist, versuchen Sie Folgendes:

  • Greifen Sie auf den Protokolldatenstrom zu.
  • Testen Sie die App lokal im Produktionsmodus. App Service führt Ihre Node.js-Apps im Produktionsmodus aus, daher müssen Sie sicherstellen, dass Ihr Projekt lokal wie erwartet im Produktionsmodus funktioniert. Beispiel:
    • Abhängig von Ihrer Datei package.json können verschiedene Pakete für den Produktionsmodus installiert werden (dependencies oder devDependencies).
    • Bestimmte Webframeworks können statische Dateien im Produktionsmodus unterschiedlich bereitstellen.
    • Bestimmte Webframeworks können benutzerdefinierte Startskripts verwenden, wenn sie im Produktionsmodus ausgeführt werden.
  • Führen Sie Ihre App in App Service im Entwicklungsmodus aus. In MEAN.js können Sie Ihre App z. B. zur Laufzeit in den Entwicklungsmodus versetzen, indem Sie die App-Einstellung NODE_ENV festlegen.

Keine Berechtigung zum Anzeigen dieses Verzeichnisses oder dieser Seite

Nachdem Sie Ihren Node.js-Code in einer nativen Windows-App in App Service bereitgestellt haben, wird möglicherweise die Meldung You do not have permission to view this directory or page im Browser angezeigt, wenn Sie zur URL Ihrer App navigieren. Dies liegt sehr wahrscheinlich daran, dass Sie keine Datei Web.config haben. (Sehen Sie sich die Vorlage und ein Beispiel an.)

Wenn Sie Ihre Dateien über Git oder eine ZIP-Bereitstellung mit aktivierter Buildautomatisierung bereitstellen, generiert die Bereitstellungs-Engine automatisch eine web.config-Datei im Webstammverzeichnis Ihrer App (%HOME%\site\wwwroot), wenn eine der folgenden Bedingungen zutrifft:

  • Ihr Projektstamm verfügt über eine package.json-Datei, die ein start-Skript definiert, das den Pfad einer JavaScript-Datei enthält.
  • Ihr Projektstamm verfügt entweder über eine server.js- oder eine app.js-Datei.

Die generierte web.config-Datei ist auf das erkannte Startskript zugeschnitten. Bei anderen Bereitstellungsmethoden müssen Sie die web.config-Datei manuell hinzufügen. Stellen Sie sicher, dass die Datei ordnungsgemäß formatiert ist.

Wenn Sie die ZIP-Bereitstellung (z. B. über Visual Studio Code) verwenden, müssen Sie die Buildautomatisierung aktivieren. Er ist nicht standardmäßig aktiviert. az webapp up verwendet die ZIP-Bereitstellung mit aktivierter Buildautomatisierung.

„robots933456“ in Protokollen

Möglicherweise wird die folgende Meldung in den Containerprotokollen angezeigt:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

Diese Meldung können Sie problemlos ignorieren. /robots933456.txt ist ein Dummy-URL-Pfad, den App Service verwendet, um zu überprüfen, ob der Container in der Lage ist, Anforderungen zu verarbeiten. Eine 404-Antwort zeigt lediglich an, dass der Pfad nicht vorhanden ist, informiert App Service aber darüber, dass der Container fehlerfrei und bereit ist, um auf Anforderungen zu antworten.

Nächste Schritte

Oder siehe in zusätzlichen Ressourcen:

Referenz zu Umgebungsvariablen und App-Einstellungen