Compilare e distribuire un'app Web Python con App Azure Container e PostgreSQL

Questo articolo fa parte di un'esercitazione su come inserire e distribuire un'app Web Python in App Contenitore di Azure. App contenitore consente di distribuire app in contenitori senza gestire un'infrastruttura complessa.

In questa parte dell'esercitazione si apprenderà come inserire e distribuire un'app Web di esempio Python (Django o Flask). In particolare, si compila l'immagine del contenitore nel cloud e la si distribuisce in App Azure Container. Si definiscono le variabili di ambiente che consentono all'app contenitore di connettersi a un'istanza del server flessibile Database di Azure per PostgreSQL, in cui l'app di esempio archivia i dati.

Questo diagramma dei servizi illustra i componenti illustrati in questo articolo: compilazione e distribuzione di un'immagine del contenitore.

Screenshot dei servizi nell'esercitazione - Distribuire un'app Python nelle app Azure Container. La sezione evidenziata è quella illustrata in questo articolo.

Ottenere l'app di esempio

Creare una copia tramite fork e clonare il codice di esempio nell'ambiente di sviluppo.

Passaggio 1: Passare al repository GitHub dell'app di esempio (Django o Flask) e selezionare Fork.

Seguire la procedura per creare una copia tramite fork della directory nell'account GitHub. È anche possibile scaricare il repository di codice direttamente nel computer locale senza creare fork o un account GitHub, ma non sarà possibile configurare CI/CD descritto più avanti nell'esercitazione.

Passaggio 2. Usare il comando git clone per clonare il repository con fork nella cartella python-container :

# Django
git clone https://github.com/$USERNAME/msdocs-python-django-azure-container-apps.git python-container

# Flask
# git clone https://github.com/$USERNAME/msdocs-python-flask-azure-container-apps.git python-container

Passaggio 3. Modificare la directory.

cd python-container

Creare un'immagine del contenitore dal codice dell'app Web

Dopo aver seguito questi passaggi, si avrà un Registro Azure Container che contiene un'immagine del contenitore Docker compilata dal codice di esempio.

I comandi dell'interfaccia della riga di comando di Azure possono essere eseguiti in Azure Cloud Shell o in una workstation con l'interfaccia della riga di comando di Azure installata.

Passaggio 1: Creare un gruppo di risorse con il comando az group create.

az group create \
--name pythoncontainer-rg \
--location <location>

<location> è uno dei valori del nome della posizione di Azure dall'output del comando az account list-locations -o table.

Passaggio 2. Creare un registro contenitori con il comando az acr create .

az acr create \
--resource-group pythoncontainer-rg \
--name <registry-name> \
--sku Basic \
--admin-enabled

<il nome> del registro deve essere univoco in Azure e contenere 5-50 caratteri alfanumerici.

È possibile visualizzare le credenziali create per l'amministratore con:

az acr credential show \
--name <registry-name> \
--resource-group pythoncontainer-rg

Passaggio 3. Accedere al Registro di sistema usando il comando az acr login .

az acr login --name <registry-name>

Il comando aggiunge "azurecr.io" al nome per creare il nome completo del Registro di sistema. In caso di esito positivo, verrà visualizzato il messaggio "Login Succeeded". Se si accede al Registro di sistema da una sottoscrizione diversa da quella in cui è stato creato il Registro di sistema, usare l'opzione --suffix .

Passaggio 4. Compilare l'immagine con il comando az acr build .

az acr build \
--registry <registry-name> \
--resource-group pythoncontainer-rg \
--image pythoncontainer:latest .

Tenere presente quanto segue:

  • Il punto (".") alla fine del comando indica il percorso del codice sorgente da compilare. Se non si esegue questo comando nella directory radice dell'app di esempio, specificare il percorso del codice.

  • Se si esegue il comando in Azure Cloud Shell, usare git clone prima di tutto per eseguire il pull del repository nell'ambiente Cloud Shell e modificare la directory nella radice del progetto in modo che il punto (".") venga interpretato correttamente.

  • Se si esce dall'opzione -t (uguale --imagea ), il comando accoda una compilazione di contesto locale senza eseguirne il push nel Registro di sistema. La compilazione senza push può essere utile per verificare che l'immagine venga compilata.

Passaggio 5. Verificare che l'immagine del contenitore sia stata creata con il comando az acr repository list .

az acr repository list --name <registry-name>

Creare un'istanza del server flessibile PostgreSQL

L'app di esempio (Django o Flask) archivia i dati delle revisioni dei ristoranti in un database PostgreSQL. In questi passaggi viene creato il server che conterrà il database.

I comandi dell'interfaccia della riga di comando di Azure possono essere eseguiti in Azure Cloud Shell o in una workstation con l'interfaccia della riga di comando di Azure installata.

Passaggio 1: Usare il comando az postgres flexible-server create per creare il server PostgreSQL in Azure. Non è insolito che questo comando venga eseguito per alcuni minuti.

az postgres flexible-server create \
   --resource-group pythoncontainer-rg \
   --name <postgres-server-name>  \
   --location <location> \
   --admin-user <admin-username> \
   --admin-password <admin-password> \
   --sku-name Standard_D2s_v3 \
   --public-access 0.0.0.0 
  • "pythoncontainer-rg" → Il nome del gruppo di risorse usato in questa esercitazione. Se è stato usato un nome diverso, modificare questo valore.

  • <postgres-server-name> → Il nome del server di database PostgreSQL. Questo nome deve essere univoco in tutto Azure. L'endpoint server è "https://< postgres-server-name.postgres.database.azure.com>". I caratteri consentiti sono "A"-"Z", "0"-"9" e "-".

  • <posizione> → Usare la stessa posizione usata per l'app Web. <location> è uno dei valori del nome della posizione di Azure dall'output del comando az account list-locations -o table.

  • <admin-username → Nome utente> per l'account amministratore. Non può essere "azure_superuser", "admin", "administrator", "root", "guest" o "public". Usare "demoadmin" per questa esercitazione.

  • <> password amministratore dell'utente amministratore. Deve contenere da 8 a 128 caratteri di tre delle categorie seguenti: lettere maiuscole, lettere minuscole, numeri e caratteri non alfanumerici.

    Importante

    Quando si creano nomi utente o password non si usa il carattere "$". Successivamente si creano variabili di ambiente con questi valori in cui il carattere "$" ha un significato speciale all'interno del contenitore Linux usato per eseguire app Python.

  • <sku-name> → Il nome del piano tariffario e della configurazione di calcolo, ad esempio "Standard_D2s_v3". Per altre informazioni, vedere Piano tariffario di Database di Azure per PostgreSQL. Per elencare gli SKU disponibili, usare az postgres flexible-server list-skus --location <location>.

  • <public-access> → usare "0.0.0.0", che consente l'accesso pubblico al server da qualsiasi servizio di Azure, ad esempio App contenitore.

Nota

Se si prevede di usare il server PostgreSQL dalla workstation locale con strumenti diversi dall'interfaccia della riga di comando di Azure, è necessario aggiungere una regola del firewall con il comando az postgres flexible-server firewall-rule create .

Creare un database nel server

A questo punto, si dispone di un server PostgreSQL. In questa sezione viene creato un database nel server.

È possibile usare il terminale interattivo PostgreSQL psql nell'ambiente locale o in Azure Cloud Shell, accessibile anche nella portale di Azure. Quando si usa psql, è spesso più facile usare Cloud Shell perché tutte le dipendenze sono incluse nella shell.

Passaggio 1: Connettersi al database con psql.

psql --host=<postgres-server-name>.postgres.database.azure.com \
     --port=5432 \
     --username=demoadmin@<postgres-server-name> \
     --dbname=postgres

Dove <postgres-server-name> è il nome del server PostgreSQL. Il comando richiederà la password di amministratore.

In caso di problemi di connessione, riavviare il database e riprovare. Se ci si connette dall'ambiente locale, l'indirizzo IP deve essere aggiunto all'elenco delle regole del firewall per il servizio di database.

Passaggio 2. Creare il database.

postgres=> Al prompt digitare:

CREATE DATABASE restaurants_reviews;

Il punto e virgola (";") alla fine del comando è necessario. Per verificare che il database sia stato creato correttamente, usare il comando \c restaurants_reviews. Digitare \? per visualizzare la Guida o \q uscire.

È anche possibile connettersi al server flessibile postgreSQL di Azure e creare un database usando Azure Data Studio o qualsiasi altro IDE che supporta PostgreSQL.

Distribuire l'app Web in App contenitore

Le app contenitore vengono distribuite in ambienti di app contenitore, che fungono da limite sicuro. Nei passaggi seguenti si crea l'ambiente, un contenitore all'interno dell'ambiente e si configura il contenitore in modo che il sito Web sia visibile esternamente.

Passaggio 1: Accedere ad Azure ed eseguire l'autenticazione, se necessario.

az login

Passaggio 2. Installare o aggiornare l'estensione per App Azure Container con il comando az extension add .

az extension add --name containerapp --upgrade

Passaggio 3. Creare un ambiente di App contenitore con il comando az containerapp env create .

az containerapp env create \
--name python-container-env \
--resource-group pythoncontainer-rg \
--location <location>

<location> è uno dei valori del nome della posizione di Azure dall'output del comando az account list-locations -o table.

Passaggio 4. Ottenere le credenziali di accesso per il Registro Azure Container.

az acr credential show -n <registry-name>

Usare il nome utente e una delle password restituite dall'output del comando.

Passaggio 5. Creare un'app contenitore nell'ambiente con il comando az containerapp create .

az containerapp create \
--name python-container-app \
--resource-group pythoncontainer-rg \
--image <registry-name>.azurecr.io/pythoncontainer:latest \
--environment python-container-env \
--ingress external \
--target-port 8000 \
--registry-server <registry-name>.azurecr.io \
--registry-username <registry-username> \
--registry-password <registry-password> \
--env-vars <env-variable-string>
--query properties.configuration.ingress.fqdn

<env-variable-string> è una stringa composta da valori separati da spazi nel formato key="value" con i valori seguenti.

  • AZURE_POSTGRESQL_HOST=<postgres-server-name.postgres.database.azure.com>
  • AZURE_POSTGRESQL_DATABASE=restaurants_reviews
  • AZURE_POSTGRESQL_USERNAME=demoadmin
  • AZURE_POSTGRESQL_PASSWORD=<db-password>
  • RUNNING_IN_PRODUCTION=1
  • AZURE_SECRET_KEY=<YOUR-SECRET-KEY>

Generare AZURE_SECRET_KEY valore usando l'output di python -c 'import secrets; print(secrets.token_hex())'.

Ecco un esempio: --env-vars AZURE_POSTGRESQL_HOST="my-postgres-server.postgres.database.azure.com" AZURE_POSTGRESQL_DATABASE="restaurants_reviews" AZURE_POSTGRESQL_USERNAME="demoadmin" AZURE_POSTGRESQL_PASSWORD="somepassword" RUNNING_IN_PRODUCTION="1" AZURE_SECRET_KEY=asdfasdfasdf.

Passaggio 7. Solo per Django, eseguire la migrazione e creare lo schema del database. Nell'app di esempio Flask viene eseguita automaticamente ed è possibile ignorare questo passaggio.

Connettersi con il comando az containerapp exec :

az containerapp exec \
--name python-container-app \
--resource-group pythoncontainer-rg

Quindi, al prompt dei comandi della shell digitare python manage.py migrate.

Non è necessario eseguire la migrazione per le revisioni del contenitore.

Passaggio 8. Testare il sito Web.

Il az containerapp create comando immesso in precedenza restituisce un URL dell'applicazione che è possibile usare per passare all'app. L'URL termina in "azurecontainerapps.io". Passare all'URL in un browser. In alternativa, è possibile usare il comando az containerapp browse .

Ecco un esempio del sito Web di esempio dopo aver aggiunto un ristorante e due recensioni.

Screenshot che mostra un esempio del sito Web di esempio compilato in questa esercitazione.

Risolvere i problemi di distribuzione

  • L'URL dell'applicazione è stato dimenticato per accedere al sito Web.

    • Nella portale di Azure passare alla pagina Panoramica dell'app contenitore e cercare l'URL dell'applicazione.
    • In VS Code passare alla visualizzazione di Azure (CTRL+MAIUSC+A) ed espandere la sottoscrizione in uso. Espandere il nodo App contenitore, quindi espandere l'ambiente gestito e fare clic con il pulsante destro del mouse su python-container-app e scegliere Sfoglia. Verrà aperto il browser con l'URL dell'applicazione.
    • Nell'interfaccia della riga di comando di Azure usare il comando az containerapp show -g pythoncontainer-rg -n python-container-app --query properties.configuration.ingress.fqdn.
  • In VS Code l'attività Compila immagine in Azure restituisce un errore.

    • Se viene visualizzato il messaggio "Errore: impossibile scaricare il contesto. Controllare se l'URL non è corretto." nella finestra Output di VS Code aggiornare il Registro di sistema nell'estensione Docker. Per aggiornare, selezionare l'estensione Docker, passare alla sezione Registries (Registri), individuare il Registro di sistema e selezionarlo.
    • Se si esegue di nuovo l'attività Compila immagine in Azure , verificare se il Registro di sistema da un'esecuzione precedente esiste e, in tal caso, usarlo.
  • Nel portale di Azure durante la creazione di un'app contenitore viene visualizzato un errore di accesso che contiene "Impossibile accedere al Registro Azure Container '<name.azurecr.io>'".

    • Questo errore si verifica quando le credenziali di amministratore nel Registro Azure Container sono disabilitate. Per controllare lo stato dell'amministratore nel portale, passare al Registro Azure Container, selezionare la risorsa Chiavi di accesso e assicurarsi che l'utente amministratore sia abilitato.
  • L'immagine del contenitore non viene visualizzata nella Registro Azure Container.

    • Controllare l'output del comando dell'interfaccia della riga di comando di Azure o dell'output di VS Code e cercare i messaggi per confermare l'esito positivo.
    • Verificare che il nome del Registro di sistema sia stato specificato correttamente nel comando di compilazione con l'interfaccia della riga di comando di Azure o nei prompt delle attività di VS Code.
    • Assicurarsi che le credenziali non siano scadute. Ad esempio, in VS Code trovare il Registro di sistema di destinazione nell'estensione Docker e aggiornare. Nell'interfaccia della riga di comando di Azure eseguire az login.
  • Il sito Web restituisce "Richiesta non valida (400)".

    • Controllare le variabili di ambiente PostgreSQL passate al contenitore. L'errore 400 indica spesso che il codice Python non è in grado di connettersi all'istanza di PostgreSQL.
    • Il codice di esempio usato in questa esercitazione verifica l'esistenza della variabile RUNNING_IN_PRODUCTIONdi ambiente contenitore , che può essere impostata su qualsiasi valore come "1".
  • Il sito Web restituisce "Not Found (404)".

    • Controllare l'URL dell'applicazione nella pagina Panoramica per il contenitore. Se l'URL dell'applicazione contiene la parola "internal", l'ingresso non viene impostato correttamente.
    • Controllare l'ingresso del contenitore. Ad esempio, in portale di Azure passare alla risorsa Ingress del contenitore e assicurarsi che l'opzione Ingresso HTTP sia abilitata e Accettazione del traffico da qualsiasi posizione sia selezionata.
  • Il sito Web non viene avviato, viene visualizzato il "timeout del flusso" o non viene restituito nulla.

    • Controllare i log.
      • Nel portale di Azure passare alla risorsa di gestione delle revisioni dell'app contenitore e controllare lo stato del provisioning del contenitore.
        • Se "Provisioning", attendere il completamento del provisioning.
        • Se "Failed", selezionare la revisione e visualizzare i log della console. Scegliere l'ordine delle colonne per visualizzare "Time Generated", "Stream_s" e "Log_s". Ordinare i log in base alla prima più recente e cercare i messaggi stderr e stdout Python nella colonna "Stream_s". L'output di Python 'print' sarà stdout messages.
      • Con l'interfaccia della riga di comando di Azure usare il comando az containerapp logs show .
    • Se si usa il framework Django, verificare se le tabelle restaurants_reviews sono presenti nel database. In caso contrario, usare una console per accedere al contenitore ed eseguire python manage.py migrate.

Passaggio successivo