Configurare un'app Node.js per il Servizio app di Azure

Le app Node.js devono essere distribuite con tutte le dipendenze di npm richieste. Il motore di distribuzione del servizio app esegue npm install --production quando si distribuisce un repository Git o quando si distribuisce un pacchetto ZIPcon l'automazione della compilazione abilitata. Se si distribuiscono i file usando FTP/S, tuttavia, è necessario caricare manualmente i pacchetti necessari.

Questa guida contiene i concetti chiave e le istruzioni per gli sviluppatori Node.js che eseguono la distribuzione nel servizio app. Se non si è mai usato Servizio app di Azure, seguire per prima cosa l'Avvio rapido di Node.js e l'esercitazione di Node.js con MongoDB.

Visualizzare la versione di Node.js

Per visualizzare la versione corrente di Node.js, eseguire il comando seguente in Cloud Shell:

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

Per visualizzare tutte le versioni di Node.js supportate, esplorare https://<sitename>.scm.azurewebsites.net/api/diagnostics/runtime o eseguire il comando seguente in Cloud Shell:

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

Per visualizzare la versione corrente di Node.js, eseguire il comando seguente in Cloud Shell:

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

Per visualizzare tutte le versioni di Node.js supportate, eseguire il comando seguente in Cloud Shell:

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

Impostare la versione di Node.js

Per impostare l'app su una versione di Node.js supportata, eseguire il comando seguente in Cloud Shell per impostare WEBSITE_NODE_DEFAULT_VERSION su una versione supportata:

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

Nota

In questo esempio viene usata la "sintassi tilde" consigliata per impostare come destinazione la versione più recente disponibile di Node.js runtime 16 nel servizio app.

Poiché il runtime viene regolarmente sottoposto a patch e aggiornato dalla piattaforma, non è consigliabile impostare come destinazione una versione/patch secondaria specifica, perché non è garantito che queste siano disponibili a causa di potenziali rischi per la sicurezza.

Nota

È necessario impostare la versione di Node.js nel package.json del progetto. Il motore di distribuzione viene eseguito in un processo separato che contiene tutte le versioni di Node.js supportate.

Per impostare l'app su una versione di Node.js supportata, eseguire il comando seguente in Cloud Shell:

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

Questa impostazione specifica la versione di Node.js da usare, sia in fase di runtime che durante il ripristino automatico dei pacchetti in Kudu.

Nota

È necessario impostare la versione di Node.js nel package.json del progetto. Il motore di distribuzione viene eseguito in un contenitore separato che contiene tutte le versioni di Node.js supportate.

Ottenere il numero di porta

L'app Node.js deve essere in ascolto della porta corretta per ricevere le richieste in ingresso.

Nel servizio app in Windows, le app Node.js sono ospitate con IISNodee l'app Node.js deve restare in ascolto della porta specificata nella variabile process.env.PORT. L'esempio seguente illustra come eseguire questa operazione in una semplice app Express:

Il servizio app imposta la variabile di ambiente PORT nel contenitore Node.js e inoltra le richieste in ingresso al contenitore in corrispondenza di tale numero di porta. Per ricevere le richieste, l'app deve restare in ascolto di tale porta usando process.env.PORT. L'esempio seguente illustra come eseguire questa operazione in una semplice app Express:

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}`)
})

Personalizzare l'automazione della compilazione

Se si distribuisce l'app usando pacchetti Git, oppure ZIP con l'automazione della compilazione abilitata, l'automazione della compilazione del servizio app esegue la sequenza seguente:

  1. Eseguire uno script personalizzato, se ne viene specificato uno da PRE_BUILD_SCRIPT_PATH.
  2. Eseguire npm install senza flag, includendo preinstall nmp e script postinstall, installando anche devDependencies.
  3. Eseguire npm run build se viene specificato uno script di compilazione nel package.json.
  4. Eseguire npm run build:azure se viene specificato uno script build:azure nel package.json.
  5. Esegue lo script personalizzato se specificato da POST_BUILD_SCRIPT_PATH.

Nota

Come descritto nella documentazione npm, gli script denominati prebuild e postbuild vengono eseguiti rispettivamente prima e dopo build, se specificati. preinstall e postinstall vengono eseguiti rispettivamente prima e dopo install.

PRE_BUILD_COMMAND e POST_BUILD_COMMAND sono variabili di ambiente vuote per impostazione predefinita. Per eseguire comandi pre-compilazione, definire PRE_BUILD_COMMAND. Per eseguire comandi post-compilazione, definire POST_BUILD_COMMAND.

Nell'esempio seguente vengono utilizzate le due variabili per specificare una serie di comandi, separate da virgole.

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"

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

Per altre informazioni sull'esecuzione del servizio app e sulla compilazione di app Node.js in Linux, vedere la documentazione di Oryx relativa al rilevamento e alla compilazione di app Node.js.

Configurare il server Node.js

I contenitori Node.js sono dotati di PM2, responsabile dei processi di produzione. È possibile configurare l'app in modo che inizi con PM2, con npm, oppure con un comando personalizzato.

Tool Scopo
Esecuzione con PM2 Scelta consigliata: uso di produzione o gestione temporanea. PM2 offre una piattaforma di gestione delle app completa.
Eseguire con avvio npm Solo sviluppo.
Eseguire con un comando personalizzato Sviluppo o gestione temporanea.

Esecuzione con PM2

Il contenitore avvia automaticamente l'app con PM2 quando uno dei file di Node.js comuni viene trovato nel progetto:

  • bin/www
  • server.js
  • app.js
  • index.js
  • hostingstart.js
  • Uno dei file PM2 seguenti: process.json o ecosystem.config.js

Inoltre, è possibile configurare un file di avvio personalizzato con le estensioni seguenti:

  • Un file .js
  • Un file PM2 con estensione .json, .config.js, yaml o .yml

Nota

A partire dal nodo 14 LTS, il contenitore non avvia automaticamente l'app con PM2. Per avviare l'app con PM2, impostare il comando di avvio su pm2 start <.js-file-or-PM2-file> --no-daemon. Assicurarsi di usare l'argomento --no-daemon perché PM2 deve essere eseguito in primo piano per il corretto funzionamento del contenitore.

Per aggiungere un file di avvio personalizzato, eseguire il comando seguente in Cloud Shell:

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

Eseguire con un comando personalizzato

Il servizio app può avviare l'app usando un comando personalizzato, ad esempio un file eseguibile come run.sh. Ad esempio, per eseguire npm run start:prod, eseguire il comando seguente in Cloud Shell:

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

Eseguire con avvio npm

Per avviare l'app usando npm start, assicurarsi che uno script start sia presente nel file package.json. Ad esempio:

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

Per usare un package.json personalizzato nel progetto, eseguire il comando seguente in Cloud Shell:

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

Eseguire il debug in modalità remota

È possibile eseguire il debug dell'app Node.js in modalità remota in Visual Studio Code se la si configura per l'esecuzione con PM2, tranne quando viene eseguita usando .config.js, .yml o yaml.

Nella maggior parte dei casi non è necessaria alcuna configurazione aggiuntiva per l'app. Se l'app viene eseguita con un file process.json (impostazione predefinita o personalizzata), deve avere una proprietà script nella radice JSON. Ad esempio:

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

Per configurare Visual Studio Code per il debug remoto, installare l'estensione del servizio app. Seguire le istruzioni nella pagina dell'estensione e accedere ad Azure in Visual Studio Code.

In Azure Explorer individuare l'app di cui si vuole eseguire il debug, fare clic con il pulsante destro del mouse e selezionare Avvia debug remoto. Selezionare per abilitare il debug remoto per l'app. Il servizio app avvia un proxy di tunnel per l'utente e collega il debugger. È quindi possibile effettuare richieste all'app e visualizzare la sospensione del debugger in corrispondenza dei punti di interruzione.

Al termine del debug, arrestare il debugger selezionando Disconnetti. Quando richiesto, fare clic su per disabilitare il debug remoto. Per disabilitarlo in un secondo momento, fare di nuovo clic con il pulsante destro del mouse sull'app in Azure Explorer e selezionare Disabilita debug remoto.

Accedere alle variabili di ambiente

Nel servizio app è possibile configurare le impostazioni dell'app al di fuori del codice dell'app. È quindi possibile accedervi usando il motivo standard Node.js. Ad esempio, per accedere a un'impostazione dell'app denominata NODE_ENV, usare il codice seguente:

process.env.NODE_ENV

Eseguire Grunt/Bower/Gulp

Per impostazione predefinita, l'automazione della compilazione del servizio app esegue npm install --production quando riconosce che un'app Node.js viene distribuita tramite Git o tramite distribuzione ZIP con automazione della compilazione abilitata. Se l'app richiede uno degli strumenti di automazione più diffusi, ad esempio Grunt, Bower o Gulp, è necessario fornire uno script di distribuzione personalizzato per eseguirlo.

Per consentire al repository di eseguire questi strumenti, è necessario aggiungerli alle dipendenze in package.json. Ad esempio:

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

Da una finestra del terminale locale, modificare la directory nella radice del repository ed eseguire i comandi seguenti:

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

La radice del repository include ora due file aggiuntivi: .deployment e deploy.sh.

Aprire deploy.sh e trovare la sezione Deployment, che è simile alla seguente:

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

Questa sezione termina con l'esecuzione di npm install --production. Aggiungere la sezione di codice necessaria per eseguire lo strumento richiesto alla fine della sezione Deployment:

Vedere l'esempio di MEAN.js, in cui lo script di distribuzione esegue anche un comando npm install personalizzato.

Bower

Questo frammento di codice esegue bower install.

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

Gulp

Questo frammento di codice esegue gulp imagemin.

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

Grunt

Questo frammento di codice esegue grunt.

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

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, esaminare l'intestazione X-Forwarded-Proto.

I framework Web più diffusi consentono di accedere alle informazioni X-Forwarded-* nel modello di app standard. In Express è possibile usare proxy di attendibilità. Ad esempio:

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

Accedere ai log di diagnostica

Per accedere ai log della console generati dall'interno del codice dell'applicazione nel servizio app, attivare la registrazione diagnostica eseguendo il comando seguente in Cloud Shell:

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

I valori possibili per --level sono: Error, Warning, Info e Verbose. Ogni livello successivo include il livello precedente. Ad esempio, Error include solo i messaggi di errore, mentre Verbose include tutti i messaggi.

Dopo aver attivato la registrazione diagnostica, eseguire il comando seguente per visualizzare il flusso di registrazione:

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

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

Nota

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

Per interrompere lo streaming dei log in qualsiasi momento, digitare Ctrl+C.

È 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.

Riscritture URL

Quando si distribuiscono app Node.js nel Servizio app di Azure per Linux, potrebbe essere necessario gestire le riscritture URL direttamente 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. Esistono diversi modi per completare la riscrittura degli URL in Node.js. Un esempio è quello del pacchetto express-urlrewrite.

Monitorare con Application Insights

Application Insights consente di monitorare le prestazioni, le eccezioni e l'utilizzo dell'applicazione senza apportare modifiche al codice. Per collegare l'agente di App Insights, passare all'app Web nel portale e selezionare Application Insights in Impostazioni, quindi selezionare Attiva Application Insights. Successivamente, selezionare una risorsa Application Insights esistente o crearne una nuova. Infine, selezionare Applica nella parte inferiore. Per instrumentare l'app Web con PowerShell, vedere queste istruzioni

Questo agente monitorerà l'applicazione Node.js lato server. Per monitorare javaScript sul lato client, aggiungere l’SDK JavaScript al progetto.

Per altre informazioni, vedere le note sulla versione dell'estensione di Application Insights.

Risoluzione dei problemi

Quando un'app Node.js funzionante si comporta in modo diverso nel servizio app o presenta errori, provare a eseguire le operazioni seguenti:

  • Accedere al flusso di log.
  • Testare l'app in locale nella modalità di produzione. Il servizio app esegue le app Node.js in modalità di produzione, quindi è necessario assicurarsi che il progetto funzioni come previsto in modalità di produzione in locale. Ad esempio:
    • A seconda del file package.json, è possibile che siano installati pacchetti diversi per la modalità di produzione (dependencies o devDependencies).
    • Alcuni framework Web possono distribuire i file statici in modo diverso in modalità di produzione.
    • Alcuni framework Web potrebbero usare script di avvio personalizzati durante l'esecuzione in modalità di produzione.
  • Eseguire l'app nel servizio app in modalità di sviluppo. Ad esempio, in MEAN.js, è possibile impostare l'app in modalità di sviluppo nel runtime impostando l'impostazione dell'appNODE_ENV.

Non si ha l'autorizzazione necessaria per visualizzare questa directory o pagina

Dopo aver distribuito il codice Node.js in un'app di Windows nativa nel servizio app, potrebbe essere visualizzato il messaggio You do not have permission to view this directory or page nel browser quando si passa all'URL dell'app. Si tratta dell'eventualità più probabile perché non si dispone di un file web.config. (vedere il modello e un esempio).

Se si distribuiscono i file usando Git o usando la distribuzione ZIP con l'automazione della compilazione abilitata, il motore di distribuzione genera un file web.config nella radice Web dell'app (%HOME%\site\wwwroot) se una delle condizioni seguenti è vera:

  • La radice del progetto ha un package.json che definisce uno script start contenente il percorso di un file JavaScript.
  • La radice del progetto ha un file server.js o app.js.

Il file web.config generato è personalizzato per lo script di avvio rilevato. Per altri metodi di distribuzione, aggiungere manualmente questo file web.config. Assicurarsi che il file sia formattato correttamente.

Se si usa la distribuzione ZIP (ad esempio, tramite Visual Studio Code), assicurarsi di abilitare l'automazione della compilazione. Non è abilitata per impostazione predefinita. az webapp up usa la distribuzione ZIP con l'automazione della compilazione abilitata.

robots933456 nei log

È possibile che nei log del contenitore venga visualizzato il messaggio seguente:

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

Questo messaggio può tranquillamente essere ignorato. /robots933456.txt è un percorso URL fittizio usato dal servizio app per verificare se il contenitore è in grado di gestire le richieste. Una risposta 404 indica semplicemente che il percorso non esiste, ma consente al servizio app di capire che il contenitore è integro e pronto per rispondere alle richieste.

Passaggi successivi

In alternativa, vedere risorse aggiuntive:

Informazioni di riferimento sulle variabili di ambiente e le impostazioni dell'app