Konfigurieren einer Linux-Python-App für Azure App Service

In diesem Artikel wird beschrieben, wie Python-Apps mit Azure App Service ausgeführt werden und wie Sie vorhandene Apps zu Azure migrieren und das Verhalten von App Service bei Bedarf anpassen können. Python-Apps müssen mit allen erforderlichen pip-Modulen bereitgestellt werden.

Die App Service-Bereitstellungs-Engine aktiviert automatisch eine virtuelle Umgebung und führt pip install -r requirements.txt für Sie aus, wenn Sie ein Git-Repository oder ein ZIP-Paketmit aktivierter Buildautomatisierung bereitstellen.

Dieser Leitfaden enthält wichtige Konzepte und Anleitungen für Python-Entwickler, die in App Service einen integrierten Linux-Container verwenden. Falls Sie Azure App Service noch nicht verwendet haben, ist es ratsam, zunächst die Python-Schnellstartanleitung und das Tutorial „Python mit PostgreSQL“ durchzuarbeiten.

Sie können für die Konfiguration entweder das Azure-Portal oder die Azure CLI verwenden:

Hinweis

Linux ist die einzige Betriebssystemoption zum Ausführen von Python-Apps in App Service. Python unter Windows wird nicht mehr unterstützt. Sie können jedoch Ihr eigenes benutzerdefiniertes Windows-Containerimage erstellen und dieses in App Service ausführen. Weitere Informationen finden Sie unter Verwenden eines benutzerdefinierten Docker-Images für Web-App für Container.

Konfigurieren der Python-Version

  • Azure-Portal: Verwenden Sie die Registerkarte Allgemeine Einstellungen auf der Seite Konfiguration. Dies ist unter Konfigurieren allgemeiner Einstellungen für Linux-Container beschrieben.

  • Azure CLI:

    • Zeigen Sie die aktuelle Python-Version mit az webapp config show an:

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

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

    • Legen Sie die Python-Version mit az webapp config set fest.

      az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "PYTHON|3.11"
      
    • Zeigen Sie alle Python-Versionen an, die in Azure App Service unterstützt werden, indem Sie az webapp list-runtimes verwenden:

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

Sie können auch eine nicht unterstützte Version von Python ausführen, indem Sie stattdessen Ihr eigenes Containerimage erstellen. Weitere Informationen finden Sie unter Verwenden eines benutzerdefinierten Docker-Images für Web-App für Container.

Anpassen der Buildautomatisierung

Mit dem Buildsystem von App Service (Bezeichnung: Oryx) werden die folgenden Schritte ausgeführt, wenn die Einstellung SCM_DO_BUILD_DURING_DEPLOYMENT beim Bereitstellen Ihrer App auf 1 gesetzt ist:

  1. Führen Sie ein benutzerdefiniertes Präbuildskript aus, sofern dies über die Einstellung PRE_BUILD_COMMAND angegeben ist. (Vom Skript können selbst auch andere Python- und Node.js-Skripts, pip- und npm-Befehle und Node-basierte Tools wie yarn, z. B. yarn install und yarn build, ausgeführt werden.)

  2. Führen Sie pip install -r requirements.txt aus. Die Datei requirements.txt muss im Stammordner des Projekts enthalten sein. Andernfalls wird vom Buildprozess ein Fehler der folgenden Art gemeldet: „setup.py oder requirements.txt nicht gefunden. pip-Installation wird nicht ausgeführt.“

  3. Wenn sich manage.py im Stammverzeichnis des Repositorys befindet (Hinweis auf Django-App), wird manage.py collectstatic ausgeführt. Wenn die Einstellung DISABLE_COLLECTSTATIC aber auf true festgelegt ist, wird dieser Schritt übersprungen.

  4. Führen Sie ein benutzerdefiniertes Postbuildskript aus, sofern dies über die Einstellung POST_BUILD_COMMAND angegeben ist. (Auch hier können vom Skript selbst andere Python- und Node.js-Skripts, pip- und npm-Befehle und Node-basierte Tools ausgeführt werden.)

Standardmäßig sind die Einstellungen für PRE_BUILD_COMMAND, POST_BUILD_COMMAND und DISABLE_COLLECTSTATIC leer.

  • Wenn Sie bei der Erstellung von Django-Apps die Ausführung von „collectstatic“ deaktivieren möchten, legen Sie die Einstellung DISABLE_COLLECTSTATIC auf true fest.

  • Legen Sie zum Ausführen von Präbuildbefehlen die Einstellung PRE_BUILD_COMMAND so fest, dass sie entweder einen Befehl, z. B. echo Pre-build command, oder einen Pfad zu einer Skriptdatei, z. B. scripts/prebuild.sh, relativ zu Ihrem Projektstamm enthält. Für alle Befehle müssen relative Pfade zum Stammordner des Projekts verwendet werden.

  • Legen Sie zum Ausführen von Postbuildbefehlen die Einstellung POST_BUILD_COMMAND so fest, dass sie entweder einen Befehl, z. B. echo Post-build command, oder einen Pfad zu einer Skriptdatei, z. B. scripts/postbuild.sh, relativ zu Ihrem Projektstamm enthält. Für alle Befehle müssen relative Pfade zum Stammordner des Projekts verwendet werden.

Weitere Einstellungen zum Anpassen der Buildautomatisierung finden Sie unter Oryx-Konfiguration.

Informationen zum Zugriff auf die Build- und Bereitstellungsprotokolle finden Sie unter Zugreifen auf Bereitstellungsprotokolle.

Weitere Informationen zur Ausführung und Erstellung von Python-Apps unter Linux durch App Service finden Sie unter Erkennung und Erstellung von Python-Apps durch Oryx.

Hinweis

Die Einstellungen PRE_BUILD_SCRIPT_PATH und POST_BUILD_SCRIPT_PATH sind mit PRE_BUILD_COMMAND und POST_BUILD_COMMAND identisch und werden aus Legacygründen unterstützt.

Eine Einstellung mit dem Namen SCM_DO_BUILD_DURING_DEPLOYMENT löst (sofern sie true oder 1 enthält) einen Oryx-Buildvorgang während der Bereitstellung aus. Die Einstellung ist auf „true“ festgelegt, wenn die Bereitstellung mit git, dem Azure CLI-Befehl az webapp up und Visual Studio Code durchgeführt wird.

Hinweis

Verwenden Sie in allen Prä- und Postbuildskripts immer relative Pfade, da sich der Buildcontainer, in dem Oryx ausgeführt wird, von dem Runtimecontainer unterscheidet, in dem die App ausgeführt wird. Verlassen Sie sich niemals auf die genaue Platzierung Ihres App-Projektordners im Container (z. B. die Platzierung unter site/wwwroot).

Migrieren von vorhandenen Anwendungen zu Azure

Vorhandene Webanwendungen können in Azure wie folgt erneut bereitgestellt werden:

  1. Quellrepository: Verwalten Sie Ihren Quellcode in einem geeigneten Repository wie GitHub, damit Sie zu einem späteren Zeitpunkt dieses Prozesses Continuous Deployment einrichten können.

    • Ihre Datei requirements.txt muss sich im Stammverzeichnis Ihres Repositorys für App Service befinden, damit die erforderlichen Pakete automatisch installiert werden können.
  2. Datenbank: Falls Ihre App von einer Datenbank abhängig ist, müssen die erforderlichen Ressourcen auch in Azure erstellt werden.

  3. App Service-Ressourcen: Erstellen Sie eine Ressourcengruppe, einen App Service-Plan und eine App Service-Web-App zum Hosten Ihrer Anwendung. Sie können das ganz einfach mit dem Azure CLI-Befehl az webapp up ausführen. Alternativ können Sie auch Ressourcen erstellen und bereitstellen, wie unter Tutorial: Bereitstellen einer Python-Web-App (Django oder Flask) mit PostgreSQL in Azure App Service gezeigt. Ersetzen Sie die Namen der Ressourcengruppe, des App Service-Plans und der Web-App durch Namen, die für Ihre Anwendung besser geeignet sind.

  4. Environment variables (Umgebungsvariablen): Falls für Ihre Anwendung Umgebungsvariablen benötigt werden, müssen Sie entsprechende App Service-Anwendungseinstellungen erstellen. Diese App Service-Einstellungen werden für Ihren Code als Umgebungsvariablen angezeigt. Dies ist im Abschnitt mit den Informationen zum Zugreifen auf Umgebungsvariablen beschrieben.

  5. App-Start: Lesen Sie den Abschnitt Startprozess des Containers weiter unten in diesem Artikel, um sich damit vertraut zu machen, wie App Service versucht, Ihre App auszuführen. Von App Service wird standardmäßig der Gunicorn-Webserver verwendet. Dieser muss dazu in der Lage sein, auf Ihr App-Objekt oder den Ordner wsgi.py zuzugreifen. Bei Bedarf können Sie den Startbefehl anpassen.

  6. Continuous Deployment: Richten Sie Continuous Deployment mit GitHub Actions, Bitbucket oder Azure Repos ein, wie im Artikel Continuous Deployment in Azure App Service beschrieben. Oder richten Sie Continuous Deployment über lokales Git ein, wie im Artikel Lokale Git-Bereitstellung in Azure App Service beschrieben.

  7. Benutzerdefinierte Aktionen: Zum Durchführen von Aktionen in dem App Service-Container, von dem Ihre App gehostet wird, z. B. Django-Datenbankmigrationen, können Sie eine Verbindung mit dem Container per SSH herstellen. Ein Beispiel für die Ausführung von Django-Datenbankmigrationen finden Sie unter Tutorial: Bereitstellen einer Django-Web-App mit PostgreSQL – Generieren von Datenbankschemas.

    • Bei Verwendung von Continuous Deployment können Sie diese Aktionen mit Postbuildbefehlen durchführen. Dies ist weiter oben unter Anpassen der Buildautomatisierung beschrieben.

Nachdem Sie diese Schritte abgeschlossen haben, sollten Sie Änderungen für Ihr Quellrepository committen können, und diese Aktualisierungen sollten dann automatisch in App Service bereitgestellt werden.

Produktionseinstellungen für Django-Apps

Für eine Produktionsumgebung wie Azure App Service sollten bei Django-Apps die Vorgaben in der Bereitstellungsprüfliste von Django (djangoproject.com) erfüllt werden.

In der folgenden Tabelle sind die Produktionseinstellungen beschrieben, die für Azure relevant sind. Diese Einstellungen werden in der Datei setting.py der App definiert.

Django-Einstellung Anleitung für Azure
SECRET_KEY Speichern Sie den Wert in einer App Service-Einstellung, wie dies unter Zugreifen auf App-Einstellungen als Umgebungsvariablen beschrieben ist. Alternativ können Sie den Wert in Azure Key Vault als „Geheimnis“ speichern.
DEBUG Erstellen Sie in App Service die Einstellung DEBUG mit dem Wert 0 (false), und laden Sie den Wert dann als Umgebungsvariable. Erstellen Sie in Ihrer Entwicklungsumgebung die Umgebungsvariable DEBUG mit dem Wert 1 (true).
ALLOWED_HOSTS In der Produktion ist es für Django erforderlich, dass Sie die URL der App im Array ALLOWED_HOSTS von settings.py einfügen. Sie können diese URL zur Laufzeit mit dem Code os.environ['WEBSITE_HOSTNAME'] abrufen. Von App Service wird die Umgebungsvariable WEBSITE_HOSTNAME automatisch auf die URL der App festgelegt.
DATABASES Definieren Sie Einstellungen in App Service für die Datenbankverbindung, und laden Sie sie als Umgebungsvariablen, um das Wörterbuch DATABASES aufzufüllen. Sie können diese Werte (vor allem Benutzername und Kennwort) auch als Azure Key Vault-Geheimnisse speichern.

Bereitstellen von statischen Dateien für Django-Apps

Wenn Ihre Django-Web-App statische Front-End-Dateien enthält, sollten Sie zunächst die Anleitung in der Django-Dokumentation zum Thema Verwalten von statischen Dateien befolgen.

Anschließend nehmen Sie für App Service die folgenden Änderungen vor:

  1. Erwägen Sie, Umgebungsvariablen (für die lokale Entwicklung) und App-Einstellungen (bei der Bereitstellung in der Cloud) zu verwenden, um die Django-Variablen STATIC_URL und STATIC_ROOT dynamisch festzulegen. Beispiel:

    STATIC_URL = os.environ.get("DJANGO_STATIC_URL", "/static/")
    STATIC_ROOT = os.environ.get("DJANGO_STATIC_ROOT", "./static/")    
    

    DJANGO_STATIC_URL und DJANGO_STATIC_ROOT können für Ihre lokalen und Cloudumgebungen wie gewünscht geändert werden. Falls diese Variablen vom Buildprozess für Ihre statischen Dateien beispielsweise in einem Ordner mit dem Namen django-static angeordnet werden, können Sie DJANGO_STATIC_URL auf /django-static/ festlegen, um die Verwendung der Standardeinstellung zu vermeiden.

  2. Wenn Sie über ein Präbuildskript verfügen, mit dem statische Dateien in einem anderen Ordner generiert werden, sollten Sie diesen Ordner in die Django-Variable STATICFILES_DIRS einfügen, damit die Dateien vom collectstatic-Prozess von Django gefunden werden können. Bei Ausführung von yarn build in Ihrem Front-End-Ordner und Erstellung des Ordners build/static mit statischen Dateien durch yarn, sollten Sie diesen Ordner wie folgt einfügen:

    FRONTEND_DIR = "path-to-frontend-folder" 
    STATICFILES_DIRS = [os.path.join(FRONTEND_DIR, 'build', 'static')]    
    

    FRONTEND_DIR wird hier verwendet, um einen Pfad zu dem Ort zu erstellen, an dem ein Buildtool wie yarn ausgeführt wird. Sie können auch hier wie gewünscht eine Umgebungsvariable und eine App-Einstellung verwenden.

  3. Fügen Sie whitenoise Ihrer Datei requirements.txt hinzu. Bei Whitenoise (whitenoise.evans.io) handelt es sich um ein Python-Paket, mit dem eine für die Produktion bestimmte Django-App leicht eigene statische Dateien bereitstellen kann. Von Whitenoise werden genau die Dateien aus dem Ordner bereitgestellt, der mit der Django-Variablen STATIC_ROOT angegeben wurde.

  4. Fügen Sie in Ihrer Datei settings.py die folgende Zeile für Whitenoise hinzu:

    STATICFILES_STORAGE = ('whitenoise.storage.CompressedManifestStaticFilesStorage')
    
  5. Ändern Sie außerdem die Listen MIDDLEWARE und INSTALLED_APPS so, dass sie Whitenoise enthalten:

    MIDDLEWARE = [                                                                   
        'django.middleware.security.SecurityMiddleware',
        # Add whitenoise middleware after the security middleware                             
        'whitenoise.middleware.WhiteNoiseMiddleware',
        # Other values follow
    ]
    
    INSTALLED_APPS = [
        "whitenoise.runserver_nostatic",
        # Other values follow
    ]
    

Bereitstellen von statischen Dateien für Flask-Apps

Wenn Ihre Flask-Web-App statische Front-End-Dateien enthält, sollten Sie zunächst die Anleitung in der Flask-Dokumentation zum Thema Verwalten von statischen Dateien befolgen. Ein Beispiel für die Bereitstellung statischer Dateien in einer Flask-Anwendung finden Sie in dem Schnellstartbeispiel zur Flask-Anwendung auf GitHub.

Um statische Dateien direkt aus einer Route Ihrer Anwendung bereitzustellen, können Sie die send_from_directory-Methode verwenden:

from flask import send_from_directory

@app.route('/reports/<path:path>')
def send_report(path):
    return send_from_directory('reports', path)

Eigenschaften von Containern

Bei der Bereitstellung in App Service werden Python-Apps in einem Linux-Docker-Container ausgeführt, der im GitHub-Repository für Python in App Service definiert ist. Sie finden Imagekonfigurationen in den versionsspezifischen Verzeichnissen.

Dieser Container verfügt über die folgenden Eigenschaften:

  • Apps werden per Gunicorn WSGI HTTP Server mit den zusätzlichen Argumenten --bind=0.0.0.0 --timeout 600 ausgeführt.

    • Sie können Konfigurationseinstellungen für Gunicorn bereitstellen, indem Sie den Startbefehl anpassen.

    • Um Ihre Web-App vor versehentlichen oder absichtlichen DDoS-Angriffen zu schützen, wird Gunicorn hinter einem Nginx-Reverseproxy ausgeführt. Dies ist unter Bereitstellen von Gunicorn (docs.gunicorn.org) beschrieben.

  • Standardmäßig enthält das Basiscontainerimage nur das Flask-Webframework, aber der Container unterstützt auch andere Frameworks, die WSGI-konform und mit Python 3.6 oder höher kompatibel sind, z. B. Django.

  • Erstellen Sie zum Installieren von zusätzlichen Paketen, z. B. Django, im Stamm Ihres Projekts die Datei requirements.txt, in der Ihre direkten Abhängigkeiten angegeben sind. App Service installiert diese Abhängigkeiten dann automatisch, wenn Sie Ihr Projekt bereitstellen.

    Die Datei requirements.txtmuss sich im Projektstamm befinden, damit die Abhängigkeiten installiert werden. Andernfalls wird vom Buildprozess ein Fehler der folgenden Art gemeldet: „setup.py oder requirements.txt nicht gefunden. pip-Installation wird nicht ausgeführt.“ Wenn dieser Fehler auftritt, sollten Sie den Speicherort Ihrer Anforderungsdatei überprüfen.

  • App Service definiert automatisch eine Umgebungsvariable mit dem Namen WEBSITE_HOSTNAME und der URL der Web-App, z. B. msdocs-hello-world.azurewebsites.net. Außerdem wird WEBSITE_SITE_NAME mit dem Namen Ihrer App definiert, z. B. msdocs-hello-world.

  • npm und Node.js sind im Container installiert, damit Sie Node-basierte Buildtools, z. B. yarn, ausführen können.

Startprozess des Containers

Beim Starten führt der Container vom Typ „App Service für Linux“ die folgenden Schritte aus:

  1. Verwenden eines benutzerdefinierten Startbefehls (sofern vorhanden)
  2. Überprüfen, ob eine Django-App vorhanden ist, und Starten von Gunicorn für die ggf. erkannte App
  3. Überprüfen, ob eine Flask-App vorhanden ist, und Starten von Gunicorn für die ggf. erkannte App
  4. Wenn keine andere App gefunden wird, können Sie eine Standard-App starten, die im Container integriert ist.

Die folgenden Abschnitte enthalten weitere Details zu den einzelnen Optionen.

Django-App

Für Django-Apps sucht App Service in Ihrem App-Code nach der Datei wsgi.py und führt dann mit dem folgenden Befehl Gunicorn aus:

# <module> is the name of the folder that contains wsgi.py
gunicorn --bind=0.0.0.0 --timeout 600 <module>.wsgi

Gehen Sie wie folgt vor, falls Sie eine präzisere Kontrolle über den Startbefehl benötigen: Verwenden Sie einen benutzerdefinierten Startbefehl, ersetzen Sie <module> durch den Namen des Ordners, der wsgi.py enthält, und fügen Sie das Argument --chdir hinzu, falls sich dieses Modul nicht im Projektstamm befindet. Verwenden Sie beispielsweise die Argumente --chdir knboard/backend config.wsgi, wenn sich die Datei wsgi.py bei Ihnen unter knboard/backend/config im Projektstamm befindet.

Fügen Sie zum Aktivieren der Produktionsprotokollierung die Parameter --access-logfile und --error-logfile so hinzu, wie dies in den Beispielen für benutzerdefinierte Startbefehle veranschaulicht wird.

Flask-App

Für Flask sucht App Service nach der Datei application.py oder app.py und startet Gunicorn:

# If application.py
gunicorn --bind=0.0.0.0 --timeout 600 application:app

# If app.py
gunicorn --bind=0.0.0.0 --timeout 600 app:app

Falls Ihr App-Hauptmodul in einer anderen Datei enthalten ist, sollten Sie einen anderen Namen für das App-Objekt verwenden. Wenn Sie zusätzliche Argumente für Gunicorn angeben möchten, können Sie einen benutzerdefinierten Startbefehl nutzen.

Standardverhalten

Wenn App Service keinen benutzerdefinierten Befehl und keine Django-App oder Flask-App findet, wird eine schreibgeschützte Standard-App ausgeführt, die sich im Ordner opt/defaultsite befindet (siehe folgende Abbildung).

Wenn Sie Code bereitgestellt haben und die Standard-App weiterhin angezeigt wird, finden Sie Informationen unter Problembehandlung: Die App wird nicht angezeigt.

Screenshot of the default App Service on Linux web page.

Erneut, wenn Sie erwarten, dass eine bereitgestellte App anstelle der Standard-App angezeigt wird, finden Sie Informationen unter Problembehandlung: Die App wird nicht angezeigt.

Anpassen des Startbefehls

Sie können das Startverhalten des Containers steuern, indem Sie entweder einen benutzerdefinierten Startbefehl oder mehrere Befehle in einer Startbefehlsdatei bereitstellen. Für eine Datei mit Startbefehlen können Sie einen beliebigen Namen wählen, z. B. startup.sh, startup.cmd, startup.txt usw.

Für alle Befehle müssen relative Pfade zum Stammordner des Projekts verwendet werden.

Geben Sie einen Startbefehl oder eine Befehlsdatei wie folgt an:

  • Azure-Portal: Wählen Sie die Seite Konfiguration der App und dann die Option Allgemeine Einstellungen aus. Geben Sie im Feld Startbefehl entweder den vollständigen Text Ihres Startbefehls oder den Namen Ihrer Startbefehlsdatei an. Klicken Sie anschließend auf Speichern, um die Änderungen zu übernehmen. Weitere Informationen finden Sie unter Konfigurieren von allgemeinen Einstellungen für Linux-Container.

  • Azure CLI: Verwenden Sie den Befehl az webapp config set mit dem Parameter --startup-file, um den Startbefehl bzw. die Datei festzulegen:

    az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<custom-command>"
    

    Ersetzen Sie <custom-command> entweder durch den vollständigen Text Ihres Startbefehls oder durch den Namen Ihrer Startbefehlsdatei.

App Service ignoriert alle Fehler, die beim Verarbeiten eines benutzerdefinierten Startbefehls oder einer Befehlsdatei auftreten, und setzt den Startprozess dann fort, indem nach Django- und Flask-Apps gesucht wird. Falls das erwartete Verhalten nicht eintritt, sollten Sie überprüfen, ob Ihr Startbefehl bzw. die Datei fehlerfrei ist und ob zusammen mit Ihrem App-Code eine Startbefehlsdatei für App Service bereitgestellt wird. Weitere Informationen finden Sie auch in den Diagnoseprotokollen. Überprüfen Sie auch die Seite Diagnose und Problembehandlung der App im Azure-Portal.

Beispiele für Startbefehle

  • Hinzugefügte Gunicorn-Argumente: Im folgenden Beispiel wird --workers=4 einer Gunicorn-Befehlszeile hinzugefügt, um eine Django-App zu starten:

    # <module-path> is the relative path to the folder that contains the module
    # that contains wsgi.py; <module> is the name of the folder containing wsgi.py.
    gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi
    

    Weitere Informationen finden Sie unter Ausführen von Gunicorn (docs.gunicorn.org). Wenn Sie automatische Skalierungsregeln verwenden, um Ihre Web-App hoch- und herunterzuskalieren, sollten Sie auch die Anzahl der Gunicorn-Worker dynamisch mithilfe der Umgebungsvariablen NUM_CORES in Ihrem Startbefehl festlegen, z. B.: --workers $((($NUM_CORES*2)+1)). Weitere Informationen zum Festlegen der empfohlenen Anzahl von Gunicorn-Workern finden Sie in den häufig gestellten Fragen zu Gunicorn.

  • Aktivieren der Produktionsprotokollierung für Django: Fügen Sie der Befehlszeile die Argumente --access-logfile '-' und --error-logfile '-' hinzu:

    # '-' for the log files means stdout for --access-logfile and stderr for --error-logfile.
    gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi --access-logfile '-' --error-logfile '-'
    

    Diese Protokolle werden im App Service-Protokolldatenstrom angezeigt.

    Weitere Informationen finden Sie unter Gunicorn-Protokollierung (docs.gunicorn.org).

  • Benutzerdefiniertes Flask-Hauptmodul: Standardmäßig wird von App Service angenommen, dass das Hauptmodul einer Flask-App application.py oder app.py lautet. Falls für Ihr Hauptmodul ein anderer Name verwendet wird, müssen Sie den Startbefehl anpassen. Wenn Sie beispielsweise über eine Flask-App verfügen, deren Hauptmodul hello.py lautet, und das Flask-App-Objekt in dieser Datei den Namen myapp hat, lautet der Befehl wie folgt:

    gunicorn --bind=0.0.0.0 --timeout 600 hello:myapp
    

    Wenn Ihr Hauptmodul in einem Unterordner, z. B. website enthalten ist, können Sie diesen Ordner mit dem Argument --chdir angeben:

    gunicorn --bind=0.0.0.0 --timeout 600 --chdir website hello:myapp
    
  • Verwenden eines anderen Servers als eines Gunicorn-Servers: Verwenden Sie für die Nutzung eines anderen Webservers, z. B. aiohttp, den entsprechenden Befehl als Startbefehl oder in der Startbefehlsdatei:

    python3.7 -m aiohttp.web -H localhost -P 8080 package.module:init_func
    

Zugreifen auf App-Einstellungen als Umgebungsvariablen

App-Einstellungen sind Werte, die in der Cloud speziell für Ihre App gespeichert werden. Dies ist unter Konfigurieren von App-Einstellungen beschrieben. Diese Einstellungen sind für Ihren App-Code als Umgebungsvariablen verfügbar, und der Zugriff darauf erfolgt mit dem Standardmuster os.environ.

Wenn Sie beispielsweise eine App-Einstellung mit dem Namen DATABASE_SERVER erstellt haben, wird der Wert dieser Einstellung mit dem folgenden Code abgerufen:

db_server = os.environ['DATABASE_SERVER']

Erkennen einer HTTPS-Sitzung

In App Service erfolgt die TLS/SSL-Terminierung (wikipedia.org) 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, können Sie dazu den Header X-Forwarded-Proto untersuchen.

if 'X-Forwarded-Proto' in request.headers and request.headers['X-Forwarded-Proto'] == 'https':
# Do something when HTTPS is used

Gängige Webframeworks ermöglichen den Zugriff auf die Information X-Forwarded-* in Ihrem App-Standardmuster. In Django können Sie beispielsweise den SECURE_PROXY_SSL_HEADER verwenden, um Django anzuweisen, den X-Forwarded-Proto-Header zu verwenden.

Zugreifen auf Diagnoseprotokolle

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.

Wählen Sie im Menü auf der linken Seite für Ihre App die Option Überwachung>Protokolldatenstrom aus, um über das Azure-Portal auf Protokolle zuzugreifen.

Zugriff auf Bereitstellungsprotokolle

Wenn Sie Ihren Code bereitstellen, führt App Service den Buildprozess aus, der weiter oben im Abschnitt Anpassen der Buildautomatisierung beschrieben wird. Da der Build in seinem eigenen Container ausgeführt wird, werden Buildprotokolle getrennt von den Diagnoseprotokollen der App gespeichert.

Führen Sie die folgenden Schritte aus, um auf die Bereitstellungsprotokolle zuzugreifen:

  1. Wählen Sie im Azure-Portal für Ihre Web-App im linken Menü Bereitstellung>Bereitstellungscenter aus.
  2. Wählen Sie auf der Registerkarte Protokolle die Commit-ID für den letzten Commit aus.
  3. Wählen Sie auf der angezeigten Seite Protokolldetails den Link Protokolle anzeigen... aus, der neben „Oryx-Build wird ausgeführt...“ angezeigt wird.

Buildprobleme, wie z. B. falsche Abhängigkeiten in requirements.txt und Fehler in Prä- oder Postbuildskripts werden in diesen Protokollen angezeigt. Fehler werden auch angezeigt, wenn Ihre Anforderungsdatei nicht exakt requirements.txt heißt oder nicht im Stammordner Ihres Projekts angezeigt wird.

Öffnen einer SSH-Sitzung im Browser

Um eine direkte SSH-Sitzung mit Ihrem Container zu öffnen, sollte Ihre App ausgeführt werden.

Fügen Sie die folgende URL in Ihren Browser ein, und ersetzen Sie <app-name> durch den Namen Ihrer App:

https://<app-name>.scm.azurewebsites.net/webssh/host

Wenn Sie noch nicht authentifiziert sind, müssen Sie sich mit Ihrem Azure-Abonnement für die Verbindung authentifizieren. Nach der Authentifizierung wird im Browser eine Shell angezeigt, über die Sie Befehle innerhalb Ihres Containers ausführen können.

SSH connection

Hinweis

Alle Änderungen, die Sie, außerhalb des Verzeichnisses /home vornehmen, werden im Container selbst gespeichert und bleiben nicht über einen Neustart der App hinaus erhalten.

Informationen zum Öffnen einer SSH-Remotesitzung von Ihrem lokalen Computer aus finden Sie unter Öffnen einer SSH-Sitzung per Remote-Shell.

Wenn Sie erfolgreich eine Verbindung mit der SSH-Sitzung hergestellt haben, sollte am unteren Rand des Fensters die Meldung „SSH-VERBINDUNG HERGESTELLT“ angezeigt werden. Wenn Fehler wie „SSH_CONNECTION_CLOSED“ oder eine Meldung, dass der Container neu gestartet wird, angezeigt werden, verhindert möglicherweise ein Fehler das Starten des App-Containers. Schritte zur Untersuchung möglicher Probleme finden Sie unter Problembehandlung.

Problembehandlung

Im Allgemeinen besteht der erste Schritt bei der Problembehandlung in der Verwendung der App Service-Diagnose:

  1. Wählen Sie im Azure-Portal für Ihre Web-App im linken Menü Diagnose und Problembehandlung aus.
  2. Wählen Sie Verfügbarkeit und Leistung aus.
  3. Überprüfen Sie die Informationen in den Optionen Anwendungsprotokolle, Containerabsturzund Containerprobleme daraufhin, wo die häufigsten Probleme angezeigt werden.

Überprüfen Sie als Nächstes die Bereitstellungsprotokolle und die App-Protokolle auf Fehlermeldungen. Diese Protokolle identifizieren häufig bestimmte Probleme, die die App-Bereitstellung oder den App-Start verhindern können. Beispielsweise kann der Build fehlschlagen, wenn Ihre Datei requirements.txt den falschen Dateinamen aufweist oder nicht im Stammordner Ihres Projekts vorhanden ist.

Die folgenden Abschnitte bieten Anleitungen zu spezifischen Problemen.

App wird nicht angezeigt

  • Die Standard-App wird angezeigt, nachdem Sie Ihren eigenen App-Code bereitgestellt haben. Die Standard-App wird angezeigt, da Sie entweder Ihren App-Code nicht in App Service bereitgestellt haben oder App Service Ihren App-Code nicht finden konnte und stattdessen die Standard-App ausgeführt hat.

    • Starten Sie App Service neu, warten Sie 15 bis 20 Sekunden, und prüfen Sie die App dann erneut.

    • Verwenden Sie SSH, um eine direkte Verbindung mit dem App Service-Container herzustellen, und stellen Sie sicher, dass Ihre Dateien unter site/wwwroot vorhanden sind. Wenn Ihre Dateien nicht vorhanden sind, führen Sie die folgenden Schritte aus:

      1. Erstellen Sie eine App-Einstellung namens SCM_DO_BUILD_DURING_DEPLOYMENT mit dem Wert 1, stellen Sie Ihren Code erneut bereit, warten Sie ein paar Minuten, und versuchen Sie dann noch mal, auf die App zuzugreifen. Weitere Informationen zum Erstellen von App-Einstellungen finden Sie unter Konfigurieren einer App Service-App im Azure-Portal.
      2. Überprüfen Sie Ihren Bereitstellungsprozess, überprüfen Sie die Bereitstellungsprotokolle, korrigieren Sie alle Fehler, und stellen Sie die App erneut bereit.
    • Wenn Ihre Dateien vorhanden sind, konnte App Service Ihre spezifische Startdatei nicht identifizieren. Überprüfen Sie, ob Ihre App so strukturiert ist, wie App Service dies für Django oder Flask erwartet, oder verwenden Sie einen benutzerdefinierten Startbefehl.

  • Im Browser wird die Meldung „Dienst nicht verfügbar“ angezeigt. Für den Browser ist ein Timeout aufgetreten, während auf eine Antwort von App Service gewartet wurde. Dies weist darauf hin, dass App Service den Gunicorn-Server gestartet hat, aber dass die App selbst nicht gestartet wurde. Diese Bedingung könnte darauf hindeuten, dass die Gunicorn-Argumente falsch sind oder dass ein Fehler im App-Code vorliegt.

    • Aktualisieren Sie den Browser. Dies gilt besonders, wenn Sie in Ihrem App Service-Plan die niedrigsten Tarife nutzen. Bei Verwendung von Free-Tarifen kann das Starten der App beispielsweise länger dauern. Sie reagiert dann wieder, nachdem Sie den Browser aktualisiert haben.

    • Überprüfen Sie, ob Ihre App so strukturiert ist, wie App Service dies für Django oder Flask erwartet, oder verwenden Sie einen benutzerdefinierten Startbefehl.

    • Untersuchen Sie den App-Protokolldatenstrom auf Fehlermeldungen. In den Protokollen werden alle Fehler im App-Code angezeigt.

„setup.py“ oder „requirements.txt“ wurde nicht gefunden

  • Für den Protokolldatenstrom wird eine Fehlermeldung der Art „setup.py oder requirements.txt nicht gefunden. pip-Installation wird nicht ausgeführt.“ angezeigt: Ihre Datei requirements.txt konnte während des Oryx-Buildprozesses nicht gefunden werden.

    • Stellen Sie eine Verbindung mit dem Container der Web-App über SSH her, und stellen Sie sicher, dass requirements.txt richtig benannt und direkt unter site/wwwroot vorhanden ist. Falls nicht, sollen Sie sicherstellen, dass sich die Datei in Ihrem Repository befindet und Teil Ihrer Bereitstellung ist. Verschieben Sie sie in den Stamm, wenn sie in einem separaten Ordner enthalten ist.

ModuleNotFoundError beim Starten der App

Wenn Ihnen eine Fehlermeldung wie ModuleNotFoundError: No module named 'example' angezeigt wird, konnte Python beim Starten der Anwendung mindestens eines Ihrer Module nicht finden. Dieser Fehler tritt am häufigsten auf, wenn Sie Ihre virtuelle Umgebung mit Ihrem Code bereitstellen. Virtuelle Umgebungen sind nicht portierbar. Daher sollten sie nicht mit dem Anwendungscode bereitgestellt werden. Lassen Sie stattdessen Oryx eine virtuelle Umgebung erstellen, und installieren Sie Ihre Pakete in der Web-App, indem Sie die App-Einstellung SCM_DO_BUILD_DURING_DEPLOYMENT erstellen und sie auf 1 festlegen. Durch diese Einstellung wird Oryx gezwungen, Ihre Pakete zu installieren, wann immer Sie eine Bereitstellung in App Service durchführen. Weitere Informationen finden Sie in diesem Artikel über die Portabilität von virtuellen Umgebungen.

Die Datenbank ist gesperrt.

Wenn Sie versuchen, die Datenbankmigration mit einer Django-App auszuführen, wird möglicherweise Folgendes angezeigt: sqlite3. OperationalError: Die Datenbank ist gesperrt.“ Der Fehler weist darauf hin, dass Ihre Anwendung eine SQLite-Datenbank verwendet, für die standardmäßig Django konfiguriert ist, statt eine Clouddatenbank wie PostgreSQL für Azure.

Überprüfen Sie die Variable DATABASES in der Datei settings.py der App, um sicherzustellen, dass Ihre App anstelle von SQLite eine Clouddatenbank verwendet.

Tritt dieser Fehler im Zusammenhang mit dem Beispiel unter Tutorial: Bereitstellen einer Django-Web-App mit PostgreSQL auf, vergewissern Sie sich, dass Sie die Schritte unter Überprüfen der Verbindungseinstellungen ausgeführt haben.

Andere Probleme

  • Kennwörter werden bei der Eingabe in der SSH-Sitzung nicht angezeigt: Aus Sicherheitsgründen blendet die SSH-Sitzung Ihr Kennwort während der Eingabe aus. Die Zeichen werden jedoch aufgezeichnet. Geben Sie also Ihr Kennwort wie gewohnt ein, und drücken Sie zum Abschluss die EINGABETASTE.

  • Befehle in der SSH-Sitzung scheinen abgeschnitten zu werden: Möglicherweise umbricht der Editor Befehle nicht, dennoch sollten Sie weiterhin ordnungsgemäß ausgeführt werden.

  • Statische Objekte werden in einer Django-App nicht angezeigt: Stellen Sie sicher, dass Sie das Whitenoise-Modul aktiviert haben.

  • Die Meldung „Schwerwiegende SSL-Verbindung ist erforderlich“ wird angezeigt: Überprüfen Sie alle Benutzernamen und Kennwörter, die für den Zugriff auf Ressourcen (wie Datenbanken) aus der App heraus verwendet werden.

Weitere Ressourcen