Condividi tramite


Configurare un'app Python in Linux per il servizio app di Azure

Questo articolo descrive come vengono eseguite le app Python nel servizio app di Azure, come eseguire la migrazione di app esistenti ad Azure e come personalizzare il comportamento del Servizio app quando necessario. Le app Python devono essere distribuite con tutti i moduli pip richiesti.

Il motore di distribuzione del Servizio app attiva automaticamente un ambiente virtuale ed esegue pip install -r requirements.txt quando si distribuisce un repository Git o quando si distribuisce un pacchetto ZIP con l'automazione della compilazione abilitata.

Questa guida illustra i concetti chiave e le istruzioni per gli sviluppatori Python che usano un contenitore Linux predefinito nel servizio app. Se il servizio app di Azure non è mai stato usato, seguire per prima cosa la guida di avvio rapido su Python e l'esercitazione su Python con PostgreSQL.

Per la configurazione, è possibile usare il portale di Azure o l'interfaccia della riga di comando di Azure:

Nota

Linux è l'unica opzione di sistema operativo per l'esecuzione di app Python nel servizio app. Python non è più supportato in Windows. Tuttavia è possibile compilare un'immagine del contenitore Windows personalizzata ed eseguirla nel servizio app. Per altre informazioni, vedere Usare un'immagine Docker personalizzata.

Configurare la versione di Python

  • Portale di Azure: usare la scheda Impostazioni generali nella pagina Configurazione, come descritto in Configurare le impostazioni generali per contenitori Linux.

  • Interfaccia della riga di comando di Azure:

    • visualizzare la versione corrente di Python con az webapp config show:

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

      Sostituire <resource-group-name> e <app-name> con i valori appropriati per l'app Web.

    • Impostare la versione di Python con az webapp config set

      az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "PYTHON|3.11"
      
    • Visualizzare tutte le versioni di Python supportate nel servizio app di Azure con az webapp list-runtimes:

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

È possibile eseguire una versione non supportata di Python creando un'immagine del contenitore personalizzata. Per altre informazioni, vedere Usare un'immagine Docker personalizzata.

Personalizzare l'automazione della compilazione

Il sistema di compilazione del servizio app, denominato Oryx, esegue i passaggi seguenti durante la distribuzione dell'app se l'impostazione dell'app SCM_DO_BUILD_DURING_DEPLOYMENT è impostata su 1:

  1. Eseguire uno script di pre-compilazione personalizzato, se tale passaggio è specificato dall'impostazione PRE_BUILD_COMMAND. (Lo script può eseguire altri script Python e Node.js, i comandi pip e npm e gli strumenti basati su Node come YARN, ad esempio yarn install e yarn build).

  2. Eseguire pip install -r requirements.txt. Il file requirements.txt deve essere presente nella cartella radice del progetto. In caso contrario, il processo di compilazione segnala l'errore: "Impossibile trovare setup.py o requirements.txt; non è in esecuzione l'installazione pip."

  3. Se nella radice del repository viene trovato manage.py (che indica un'app Django), esegue manage.py collectstatic. Tuttavia, se l'impostazione DISABLE_COLLECTSTATIC è true, questo passaggio viene ignorato.

  4. Eseguire uno script di post-compilazione personalizzato, se tale passaggio è specificato dall'impostazione POST_BUILD_COMMAND. (Anche in questo caso, lo script può eseguire altri script Python e Node.js, i comandi pip e npm e gli strumenti basati su Node).

Per impostazione predefinita, le impostazioni PRE_BUILD_COMMAND, POST_BUILD_COMMAND e DISABLE_COLLECTSTATIC sono vuote.

  • Per disabilitare l'esecuzione di collectstatic durante la compilazione di app Django, impostare DISABLE_COLLECTSTATIC su true.

  • Per eseguire i comandi di pre-compilazione, impostare PRE_BUILD_COMMAND in modo che contenga un comando, come echo Pre-build command, o il percorso di un file script relativo alla radice del progetto, ad esempio scripts/prebuild.sh. Tutti i comandi devono usare percorsi relativi alla cartella radice del progetto.

  • Per eseguire i comandi di post-compilazione, impostare POST_BUILD_COMMAND in modo che contenga un comando, come echo Post-build command, o il percorso di un file di script relativo alla radice del progetto, ad esempio scripts/postbuild.sh. Tutti i comandi devono usare percorsi relativi alla cartella radice del progetto.

Per altre impostazioni per personalizzare l'automazione della compilazione, vedere Configurazione di Oryx.

Per accedere ai log di compilazione e distribuzione, vedere Accedere ai log di distribuzione.

Per altre informazioni sull'esecuzione del servizio app e sulla compilazione di app Python in Linux, vedere come vengono rilevate e compilate le app Python in Oryx.

Nota

Le impostazioni PRE_BUILD_SCRIPT_PATH e POST_BUILD_SCRIPT_PATH sono identiche a PRE_BUILD_COMMAND e POST_BUILD_COMMAND e sono supportate per motivi di compatibilità legacy.

Un'impostazione denominata SCM_DO_BUILD_DURING_DEPLOYMENT, se contiene true o 1, attiva una compilazione Oryx che viene eseguita durante la distribuzione. L'impostazione è true quando si esegue la distribuzione usando Git, il comando dell'interfaccia della riga di comando di Azure az webapp up e Visual Studio Code.

Nota

Usare sempre percorsi relativi negli script di pre- e post-compilazione, perché il contenitore di compilazione in cui viene eseguito Oryx è diverso dal contenitore di runtime in cui viene eseguita l'app. Non fare mai affidamento sul posizionamento esatto della cartella di progetto dell'app all'interno del contenitore, ad esempio che si trova in site/wwwroot.

Eseguire la migrazione delle applicazioni esistenti ad Azure

Le applicazione Web esistenti possono essere ridistribuite in Azure come indicato di seguito:

  1. Repository di origine: gestire il codice sorgente in un repository appropriato come GitHub, che consente di configurare la distribuzione continua successivamente, in questo processo.

    • Il file requirements.txt deve trovarsi alla radice del repository affinché il servizio app installi automaticamente i pacchetti necessari.
  2. Database: se l'app dipende da un database, creare anche le risorse necessarie in Azure.

  3. Risorse del servizio app: creare un gruppo di risorse, un piano di servizio app e un'app Web del Servizio app per ospitare l'applicazione. È possibile eseguire facilmente quest’operaizone tramite il comando dell'interfaccia della riga di comando di Azure az webapp up. In alternativa, creare e distribuire LE risorse come illustrato in Esercitazione: Distribuire un'app Web Python (Django o Flask) con PostgreSQL. Sostituire i nomi del gruppo di risorse, del piano di Servizio app e dell'app Web in base ai requisiti dell'applicazione.

  4. Variabili di ambiente: se l'applicazione richiede variabili di ambiente, creare impostazioni dell'applicazione del servizio app equivalenti. Queste impostazioni del Servizio app vengono visualizzate nel codice come variabili di ambiente, come descritto in Accedere a variabili di ambiente.

  5. Avvio dell'app: esaminare la sezione processo di avvio del contenitore più avanti in questo articolo per comprendere in che modo il Servizio app tenta di eseguire l'app. Il servizio app usa il server Web Gunicorn per impostazione predefinita, che deve essere in grado di trovare l'oggetto app o la cartella wsgi.py. Se necessario, è possibile Personalizzare il comando di avvio.

  6. distribuzione continua: configurare la distribuzione continua da GitHub Actions, Bitbucket o Azure Repos, come descritto nell'articolo Distribuzione continua nel servizio app di Azure. In alternativa, configurare la distribuzione continua da Git locale, come descritto nell'articolo Distribuzione Git locale nel servizio app di Azure.

  7. Azioni personalizzate: per eseguire azioni all'interno del contenitore del servizio app che ospita l'app, ad esempio le migrazioni di database Django, è possibile connettersi al contenitore tramite SSH. Per un esempio di esecuzione di migrazioni del database Django, vedere Esercitazione: Distribuire un'app Web Django con PostgreSQL - Generare lo schema del database.

Una volta completati questi passaggi, sarà possibile eseguire il commit delle modifiche nel repository di origine e distribuire automaticamente tali aggiornamenti nel servizio app.

Impostazioni di produzione per le app Django

Per un ambiente di produzione come il servizio app di Azure, le app Django devono seguire l'elenco di controllo della distribuzione di Django.

La tabella seguente descrive le impostazioni di produzione pertinenti per Azure. Queste impostazioni sono definite nel file setting.py dell'app.

Impostazione di Django Istruzioni per Azure
SECRET_KEY Archiviare il valore in un'impostazione del servizio app, come descritto in Accedere alle impostazioni dell'app come variabili di ambiente. In alternativa, è possibile archiviare il valore come segreto in Azure Key Vault.
DEBUG Creare un'impostazione DEBUG nel servizio app con il valore 0 (false), quindi caricare il valore come variabile di ambiente. Nell'ambiente di sviluppo creare una variabile di ambiente DEBUG con il valore 1 (true).
ALLOWED_HOSTS In produzione, Django richiede di includere l'URL dell'app nella matrice ALLOWED_HOSTS di settings-py. È possibile recuperare questo URL in fase di esecuzione con il codice os.environ['WEBSITE_HOSTNAME']. Il servizio app imposta automaticamente la variabile di ambiente WEBSITE_HOSTNAME sull'URL dell'app.
DATABASES Definire le impostazioni nel servizio app per la connessione al database e caricarle come variabili di ambiente per popolare il dizionario DATABASES. In alternativa, è possibile archiviare i valori (in particolare, il nome utente e la password) come segreti di Azure Key Vault.

Gestire i file statici per le app Django

Se l'app Web Django include file front-end statici, seguire prima le istruzioni riportate in Gestione dei file statici nella documentazione di Django.

Per il servizio app, è quindi necessario apportare le modifiche seguenti:

  1. È consigliabile usare le variabili di ambiente (per lo sviluppo locale) e le Impostazioni app (durante la distribuzione nel cloud) per impostare dinamicamente le variabili Django STATIC_URL e STATIC_ROOT. Ad esempio:

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

    DJANGO_STATIC_URL e DJANGO_STATIC_ROOT possono essere modificati in base alle esigenze per ambienti locali e cloud. Ad esempio, se il processo di compilazione per i file statici li inserisce in una cartella denominata django-static, è possibile impostare DJANGO_STATIC_URL su /django-static/ per evitare di usare l'impostazione predefinita.

  2. Se si dispone di uno script di pre-compilazione che genera file statici in una cartella diversa, includere tale cartella nella variabile Django STATICFILES_DIRS, così che possano essere trovati dal processo collectstatic di Django. Ad esempio, se si esegue yarn build nella cartella front-end e YARN genera una cartella build/static contenente file statici, includere tale cartella come indicato di seguito:

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

    In questo caso, FRONTEND_DIR è usato per compilare un percorso in cui viene eseguito uno strumento di compilazione come YARN. È possibile usare di nuovo una variabile di ambiente e l'impostazione dell'app come desiderato.

  3. Aggiungere whitenoise al file requirements.txt. Whitenoise (whitenoise.evans.io) è un pacchetto Python che semplifica la gestione di file statici da parte di un'app Django di produzione. Whitenoise gestisce specificamente i file presenti nella cartella specificata dalla variabile Django STATIC_ROOT.

  4. Nel file settings.py, aggiungere la riga seguente per Whitenoise:

    STATICFILES_STORAGE = ('whitenoise.storage.CompressedManifestStaticFilesStorage')
    
  5. Modificare anche gli elenchi MIDDLEWARE e INSTALLED_APPS in modo da includere Whitenoise:

    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
    ]
    

Gestire i file statici per le app Flask

Se l'app Web Flask include file front-end statici, seguire prima le istruzioni sulla gestione dei file statici nella documentazione di Flask. Per un esempio di gestione di file statici in un'applicazione Flask, vedere l'applicazione Flask campione in GitHub.

Per gestire i file statici direttamente da una route nell'applicazione, è possibile usare il metodo send_from_directory:

from flask import send_from_directory

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

Caratteristiche del contenitore

Quando vengono distribuite nel servizio app, le app Python vengono eseguite in un contenitore Docker Linux definito nel repository GitHub di Python per il servizio app. È possibile trovare le configurazioni delle immagini all'interno delle directory specifiche della versione.

Questo contenitore presenta le caratteristiche seguenti:

  • Le app vengono eseguite con il Server HTTP WSGI Gunicorn, usando gli argomenti extra --bind=0.0.0.0 --timeout 600.

  • Per impostazione predefinita, l'immagine di base del contenitore include solo il framework Web Flask, ma il contenitore supporta altri framework conformi a WSGI e compatibili con Python 3.6 e versioni successive, come ad esempio Django.

  • Per installare altri pacchetti, ad esempio Django, creare un file requirements.txt nella radice del progetto che specifica le dipendenze dirette. Il servizio app quindi installa automaticamente queste dipendenze quando si distribuisce il progetto.

    Per l'installazione delle dipendenze, il file requirements.txt deve essere presente nella radice del progetto. In caso contrario, il processo di compilazione segnala l'errore: "Impossibile trovare setup.py o requirements.txt; non è in esecuzione l'installazione pip." Se si verifica questo errore, verificare la posizione del file di requisiti.

  • Il servizio app definisce automaticamente una variabile di ambiente denominata WEBSITE_HOSTNAME con l'URL dell'app Web, ad esempio msdocs-hello-world.azurewebsites.net. Definisce anche WEBSITE_SITE_NAME con il nome dell'app, ad esempio msdocs-hello-world.

  • npm e Node.js vengono installati nel contenitore in modo da poter eseguire strumenti di compilazione basati su Node, ad esempio YARN.

Processo di avvio del contenitore

Durante l'avvio il servizio app in un contenitore Linux esegue i passaggi seguenti:

  1. Usa un comando di avvio personalizzato, se specificato.
  2. Verifica l'esistenza di un'app Django e avvia Gunicorn per essa, se rilevata.
  3. Verifica l'esistenza di un'app Flask e avvia Gunicorn per essa, se rilevata.
  4. Se non vengono trovate altre app, avvia un'app predefinita integrata nel contenitore.

Le sezioni seguenti forniscono altre informazioni dettagliate aggiuntive per ogni opzione.

App Django

Per le app Django il servizio app cerca un file denominato wsgi.py all'interno del codice dell'app e quindi esegue Gunicorn usando il comando seguente:

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

Per avere un controllo più specifico sul comando di avvio, usare un comando di avvio personalizzato, sostituire <module> con il nome della cartella contenente wsgi.py, quindi aggiungere un argomento --chdir se tale modulo non è presente nella radice del progetto. Ad esempio, se il file wsgi.py si trova in knboard/backend/config rispetto alla radice del progetto, usare gli argomenti --chdir knboard/backend config.wsgi.

Per abilitare la registrazione di produzione, aggiungere i parametri --access-logfile e --error-logfile, come illustrato negli esempi per i comandi di avvio personalizzati.

App Flask

Per Flask il servizio app cerca un file denominato application.py o app.py e avvia Gunicorn come segue:

# 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

Se il modulo principale dell'app è contenuto in un file diverso, usare un nome diverso per l'oggetto app. Se si desidera fornire altri argomenti a Gunicorn, usare un comando di avvio personalizzato.

Comportamento predefinito

Se il servizio app non trova un comando personalizzato, un'app Django o un'app Flask, verrà eseguita un'app predefinita di sola lettura che si trova nella cartella opt/defaultsite, come illustrato nell'immagine seguente.

Se il codice è stato distribuito e viene ancora visualizzata l'app predefinita, vedere Risoluzione dei problemi: l'app non viene visualizzata.

Screenshot del servizio app predefinito nella pagina Web Linux.

Personalizzare un comando di avvio

È possibile controllare il comportamento di avvio del contenitore specificando un comando di avvio personalizzato oppure più comandi in un file di comandi di avvio. Per un file di comandi di avvio è possibile usare qualsiasi nome, ad esempio startup.sh, startup.cmd, startup.txt e così via.

Tutti i comandi devono usare percorsi relativi alla cartella radice del progetto.

Per specificare un comando di avvio o un file di comandi:

  • Portale di Azure: selezionare la pagina Configurazione dell'app, quindi selezionare Impostazioni generali. Nel campo Comando di avvio inserire il testo completo del comando di avvio o il nome del file di comandi di avvio. Quindi selezionare Salva per applicare le modifiche. Vedere Configurare le impostazioni generali per i contenitori Linux.

  • Interfaccia della riga di comando di Azure: usare il comando az webapp config set con il parametro --startup-file per impostare il comando di avvio o il file:

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

    Sostituire <custom-command> con il testo completo del comando di avvio o con il nome del file di comandi di avvio.

Il servizio app ignora gli eventuali errori che possono verificarsi durante l'elaborazione di un comando di avvio o di un file, quindi continua il processo di avvio cercando le app Django e Flask. Se il comportamento non è quello previsto, controllare che il comando di avvio o il file sia privo di errori e che nel servizio app venga distribuito un file di comandi di avvio insieme al codice dell'app. Per altre informazioni, controllare i log di diagnostica. Controllare anche la pagina Diagnostica e risoluzione dei problemi nel portale di Azure.

Comandi di avvio di esempio

  • Aggiunta di argomenti Gunicorn: l'esempio seguente aggiunge l’argomento --workers=4 a una riga di comando Gunicorn per avviare un'app Django:

    # <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
    

    Per altre informazioni, vedere Eseguire Gunicorn. Se si usano regole di scalabilità automatica per ridimensionale le prestazioni dell'app Web, è necessario inoltre impostare dinamicamente il numero di ruoli di lavoro di Gunicorn usando la variabile di ambiente NUM_CORES nel comando di avvio, ad esempio: --workers $((($NUM_CORES*2)+1)). Per altre informazioni sull'impostazione del numero consigliato di ruoli di lavoro Gunicorn, vedere domande frequenti su Gunicorn

  • Abilitare la registrazione di produzione per Django: aggiungere alla riga di comando gli argomenti --access-logfile '-' e --error-logfile '-':

    # '-' 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 '-'
    

    Questi log verranno visualizzati nel flusso di registrazione del servizio app.

    Per altre informazioni, vedere Registrazione di Gunicorn.

  • Modulo principale Flask personalizzato: per impostazione predefinita, il servizio app presuppone che il modulo principale di un'app Flask sia application.py o app.py. Se il modulo principale usa un nome diverso, è necessario personalizzare il comando di avvio. Ad esempio, se si ha un'app Flask il cui modulo principale è hello.py e l'oggetto app Flask in tale file è denominato myapp, il comando sarà come segue:

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

    Se il modulo principale è contenuto in una sottocartella, ad esempio website, specificare tale cartella con l'argomento --chdir:

    gunicorn --bind=0.0.0.0 --timeout 600 --chdir website hello:myapp
    
  • Usare un server non Gunicorn: per usare un server Web diverso, ad esempio aiohttp, usare il comando appropriato come comando di avvio o nel file del comando di avvio:

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

Accedere alle impostazioni dell'app come variabili di ambiente

Le impostazioni dell'app sono valori specificamente archiviati nel cloud, come descritto in Configurare le impostazioni dell'app. Queste impostazioni sono disponibili per il codice dell'app come variabili di ambiente e sono accessibili tramite il modello os.environ standard.

Se ad esempio è stata creata un'impostazione dell'app denominata DATABASE_SERVER, il codice seguente recupera il relativo valore:

db_server = os.environ['DATABASE_SERVER']

Rilevare una sessione HTTPS

Nel servizio app la terminazione TLS/SSL si verifica nei servizi di bilanciamento del carico di rete, pertanto tutte le richieste HTTPS raggiungono l'app come richieste HTTP non crittografate. Se la logica dell'app deve controllare se le richieste degli utenti sono crittografate o meno, esaminare l'intestazione X-Forwarded-Proto.

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

I framework Web più diffusi consentono di accedere alle informazioni X-Forwarded-* nel modello di app standard. Ad esempio, in Django è possibile usare SECURE_PROXY_SSL_HEADER per indicare a Django di usare l'intestazione X-Forwarded-Proto.

Accedere ai log di diagnostica

È possibile accedere ai log della console generati dall'interno del contenitore.

Prima di tutto attivare la registrazione del contenitore eseguendo questo comando:

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

Sostituire <app-name> e <resource-group-name> con i valori appropriati per l'app Web.

Dopo che la registrazione del contenitore è attivata, eseguire il comando seguente per visualizzare il flusso di registrazione:

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

Se i log di console non sono immediatamente visibili, controllare nuovamente dopo 30 secondi.

Per interrompere lo streaming dei log in qualsiasi momento, premere CTRL+C.

È anche possibile ispezionare i file di log in un browser all'indirizzo https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Per accedere ai log tramite il portale di Azure, selezionare Monitoraggio>Flusso di registrazione nel menu sinistro dell'app.

Accedere ai log di distribuzione

Quando si distribuisce il codice, il servizio app esegue il processo di compilazione descritto in precedenza nella sezione Personalizzare l'automazione della compilazione. Poiché la compilazione viene eseguita nel proprio contenitore, i log di compilazione vengono archiviati separatamente dai log di diagnostica dell'app.

Usare la procedura seguente per accedere ai log di distribuzione:

  1. Nel portale di Azure per l'app Web selezionare Distribuzione>Centro distribuzione nel menu a sinistra.
  2. Nella scheda Log selezionare il valore di ID commit relativo al commit più recente.
  3. Nella pagina Dettagli log visualizzata, selezionare il collegamento Mostra log mostrato accanto al messaggio che indica che è in corso l'esecuzione della build oryx.

In questi log verranno visualizzati i problemi di compilazione, ad esempio dipendenze non corrette nel file requirements.txt, ed errori negli script di pre- o post-compilazione. Inoltre, verranno visualizzati errori se il file dei requisiti non è denominato requirements.txt o se non è presente nella cartella radice del progetto.

Aprire una sessione SSH nel browser

Per aprire una sessione SSH diretta con il contenitore, l'app deve essere in esecuzione.

Incollare l'URL seguente nel browser e sostituire <app-name> con il nome dell'app:

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

Se non lo si è già fatto, per connettersi è necessario eseguire l'autenticazione con la sottoscrizione di Azure. Al termine dell'autenticazione viene visualizzata una shell nel browser, in cui è possibile eseguire i comandi all'interno del contenitore.

Connessione SSH

Nota

Le eventuali modifiche apportate all'esterno della directory /home vengono archiviate nel contenitore stesso e non persistono oltre il riavvio dell'app.

Per aprire una sessione SSH remota dal computer locale, vedere Aprire una sessione SSH dalla shell remota.

Una volta stabilita una connessione con la sessione SSH, nella parte inferiore della finestra verrà visualizzato un messaggio analogo a "Connessione SSH stabilita". Se vengono visualizzati errori come "SSH_CONNECTION_CLOSED" o un messaggio che indica che il contenitore verrà riavviato, è possibile che un errore impedisca l'avvio del contenitore dell'app. Per analizzare i possibili problemi, vedere Risoluzione dei problemi.

Riscritture URL

Quando si distribuiscono applicazioni Python nel Servizio app di Azure per Linux, potrebbe essere necessario gestire le riscritture URL all'interno dell'applicazione. Questo è particolarmente utile per garantire che specifici modelli di URL vengano reindirizzati agli endpoint corretti, senza basarsi su configurazioni del server Web esterne. Per le applicazioni Flask, per ottenere questo risultato è possibile usare processori URL e middleware personalizzati. Nelle applicazioni Django, l’affidabile dispatcher URL consente una gestione efficiente delle riscritture degli URL.

Risoluzione dei problemi

In generale, il primo passaggio nella risoluzione dei problemi consiste nell'usare la diagnostica del Servizio app:

  1. Nel portale di Azure per l'app Web selezionare Diagnostica e risoluzione dei problemi nel menu a sinistra.
  2. Selezionare Disponibilità e prestazioni.
  3. Esaminare le informazioni contenute nelle opzioni Log applicazione, Arresto anomale del contenitore e Problemi del contenitore, in cui verranno visualizzati i problemi più comuni.

Esaminare quindi i log di distribuzione e i log dell'app per individuare eventuali messaggi di errore. Questi log identificano spesso problemi specifici che possono impedire la distribuzione o l'avvio dell'app. La compilazione può ad esempio non riuscire se il file requirements.txt ha un nome errato o non è presente nella cartella radice del progetto.

Le sezioni seguenti forniscono materiale sussidiario per problemi specifici.

L'app non viene visualizzata

  • Dopo avere distribuito il codice app personalizzato viene visualizzata l'app predefinita. L'app predefinita viene visualizzata perché il codice dell'app personalizzata non è stato distribuito nel servizio app o perché il servizio app non ha trovato il codice dell'app personalizzata e ha quindi eseguito l'app predefinita.

    • Riavviare il servizio app, attendere 15-20 secondi e verifica di nuovo l'app.

    • Usare SSH per connettersi direttamente al contenitore del servizio app e verificare che i file siano presenti in site/wwwroot. Se i file non esistono, seguire questa procedura:

      1. Creare un'impostazione dell'app denominata SCM_DO_BUILD_DURING_DEPLOYMENT con il valore 1, ridistribuire il codice, attendere alcuni minuti, quindi provare di nuovo ad accedere all'app. Per altre informazioni sulla creazione di impostazioni dell'app, vedere Configurare un'app del servizio app nel portale di Azure.
      2. Esaminare il processo di distribuzione, controllare i log di distribuzione, correggere eventuali errori e ridistribuire l'app.
    • Se i file sono presenti, il servizio app non è riuscito a identificare il file di avvio specifico. Verificare che l'app sia strutturata come prevista dal servizio app per Django o Flask oppure usare un comando di avvio personalizzato.

  • Nel browser viene visualizzato il messaggio "Servizio non disponibile". Si è verificato un timeout del browser durante l'attesa della risposta del servizio app, che indica che il servizio app ha avviato il server Gunicorn, ma l'app non è stata avviata. Questa condizione può indicare che gli argomenti di Gunicorn non sono corretti o che si è verificato un errore nel codice dell'app.

    • Ricaricare la pagina del browser, in particolare se si usano i piani tariffari inferiori nel piano di Servizio app. Ad esempio, l'avvio dell'app potrebbe richiedere più tempo quando si usano livelli gratuiti e diventare reattiva dopo aver ricaricato la pagina del browser.

    • Verificare che l'app sia strutturata come prevista dal servizio app per Django o Flask oppure usare un comando di avvio personalizzato.

    • Esaminare il flusso dei log dell'app per individuare eventuali messaggi di errore. I log visualizzano tutti gli errori del codice dell'app.

Non è stato possibile trovare setup.py o requirements.txt

  • Il flusso di log mostra "Impossibile trovare setup.py o requirements.txt; non è in esecuzione l'installazione pip.": il processo di compilazione Oryx non è riuscito a trovare il file requirements.txt.

    • Connettersi al contenitore dell'app Web tramite SSH e verificare che il file requirements.txt abbia il nome corretto e si trovi direttamente in site/wwwroot. Se non è esistente, assicurarsi che il file esista nel repository e che sia incluso nella distribuzione. Se è disponibile in una cartella separata, spostarlo nella radice.

ModuleNotFoundError all'avvio dell'app

Se viene visualizzato un errore del tipo ModuleNotFoundError: No module named 'example', all'avvio dell'applicazione Python non ha potuto trovare uno o più moduli. Questo errore si verifica più spesso se la distribuzione dell'ambiente virtuale avviene scrivendo codice. Poiché gli ambienti virtuali non sono portabili, un ambiente virtuale non deve essere distribuito con il codice dell'applicazione. Invece, lasciare che Oryx crei un ambiente virtuale e installi i pacchetti nell'app Web creando un'impostazione dell'app, SCM_DO_BUILD_DURING_DEPLOYMENT e impostandola su 1. Questa impostazione forza Oryx a installare i pacchetti ogni volta che si esegue la distribuzione nel servizio app. Per altre informazioni, vedere questo articolo sulla portabilità dell'ambiente virtuale.

Il database è bloccato

Quando si tenta di eseguire migrazioni di database con un'app Django, si potrebbe visualizzare la dicitura "sqlite3. OperationalError: il database è bloccato." L'errore indica che anziché usare un database cloud, ad esempio Database di Azure per PostgreSQL, l'applicazione usa un database SQLite per il quale Django è configurato per impostazione predefinita.

Controllare la variabile DATABASES nel file di settings.py dell'app per accertare che l'app usi un database cloud anziché SQLite.

Se si verifica questo errore con l'esempio in Esercitazione: Distribuire un'app Web Django con PostgreSQL, verificare di aver completato i passaggi descritti in Verificare le impostazioni di connessione.

Altri problemi

  • Le password non vengono visualizzate nella sessione SSH quando vengono digitate: per motivi di sicurezza, la sessione SSH mantiene nascosta la password durante la digitazione. Tuttavia, i caratteri vengono registrati, quindi digitare la password come di consueto e selezionare INVIO al termine dell’operazione.

  • I comandi nella sessione SSH sembrano essere tagliati: l'editor potrebbe non star eseguendo il word-wrapping dei comandi, ma questi dovrebbero comunque essere eseguiti correttamente.

  • Gli asset statici non vengono visualizzati in un'app Django: assicurarsi di aver abilitato il modulo WhiteNoise.

  • Viene visualizzato il messaggio "Connessione SSL irreversibile obbligatoria": controllare eventuali nomi utente e password usati per accedere alle risorse (ad esempio i database) dall'interno dell'app.