Configuración de una aplicación de Node.js para Azure App Service

Las aplicaciones de Node.js deben implementarse con todas las dependencias de NPM. El motor de implementación de App Service ejecuta npm install --production automáticamente al implementar un repositorio de Git o un paquete Zipcon la automatización de compilaciones habilitada. Sin embargo, si implementa los archivos con FTP/S, deberá cargar manualmente los paquetes necesarios.

Esta guía incluye conceptos clave e instrucciones para los desarrolladores de Node.js que realizan implementaciones en App Service. Si nunca ha usado Azure App Service, siga primero la guía de inicio rápido de Node.js y el tutorial de Node.js con MongoDB.

Mostrar la versión de Node.js

Para mostrar la versión actual de Node.js, ejecute el siguiente comando en Cloud Shell:

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

Para mostrar todas las versiones compatibles de Node.js, vaya a https://<sitename>.scm.azurewebsites.net/api/diagnostics/runtime o ejecute el siguiente comando en Cloud Shell:

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

Para mostrar la versión actual de Node.js, ejecute el siguiente comando en Cloud Shell:

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

Para mostrar todas las versiones compatibles de Node.js, ejecute el siguiente comando en Cloud Shell:

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

Establecer la versión de Node.js

Para establecer la aplicación en una versión compatible de Node.js, ejecute el siguiente comando en Cloud Shell para configurar WEBSITE_NODE_DEFAULT_VERSION en una versión compatible:

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

Nota

En este ejemplo se usa la "sintaxis de tilde" recomendada para usar como destino la versión más reciente disponible del entorno de ejecución de Node.js 16 en App Service.

Dado que la plataforma revisa y actualiza periódicamente el entorno de ejecución, no se recomienda que el destino sea una versión o revisión secundarias concretas, ya que no se garantiza que estén disponibles debido a posibles riesgos de seguridad.

Nota

Debe establecer la versión de Node.js en el archivo package.json del proyecto. El motor de implementación se ejecuta en un proceso independiente que contiene todas las versiones compatibles de Node.js.

Para establecer la aplicación en una versión compatible de Node.js, ejecute el siguiente comando en Cloud Shell:

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

Esta configuración especifica la versión de Node.js que usa, tanto en tiempo de ejecución como durante la restauración automatizada de paquetes en Kudu.

Nota

Debe establecer la versión de Node.js en el archivo package.json del proyecto. El motor de implementación se ejecuta en un contenedor independiente que contiene todas las versiones compatibles de Node.js.

Obtención del número de puerto

La aplicación de Node.js debe escuchar al puerto correcto para recibir las solicitudes entrantes.

En App Service de Windows, las aplicaciones de Node.js se hospedan con IISNode y la aplicación de Node.js debe escuchar el puerto especificado en la variable process.env.PORT. En el ejemplo siguiente se muestra cómo hacerlo en una sencilla aplicación Rápida:

App Service establece la variable de entorno PORT en el contenedor de Node.js y reenvía las solicitudes entrantes al contenedor en ese número de puerto. Para recibir las solicitudes, la aplicación debe escuchar ese puerto mediante process.env.PORT. En el ejemplo siguiente se muestra cómo hacerlo en una sencilla aplicación Rápida:

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

Personalización de la automatización de compilaciones

Si implementa la aplicación mediante paquetes Git o zip con la automatización de compilaciones activada, la automatización de compilaciones de App Service se ejecutará en este orden:

  1. Ejecute el script personalizado si lo especifica PRE_BUILD_SCRIPT_PATH.
  2. Ejecute npm install sin marcas, lo que incluye los scripts de npm preinstall y postinstall y también instala devDependencies.
  3. Ejecute npm run build si se especifica un script de compilación en package.json.
  4. Ejecute npm run build:azure si se especifica un script build:azure en package.json.
  5. Ejecute el script personalizado si lo especifica POST_BUILD_SCRIPT_PATH.

Nota

Como se describe en la documentación de npm, los scripts denominados prebuild y postbuild se ejecutan antes y después de build, respectivamente, si se especifican. preinstall y postinstall ejecutan antes y después de install, respectivamente.

PRE_BUILD_COMMAND y POST_BUILD_COMMAND son variables de entorno que, de forma predeterminada, están vacías. Para ejecutar comandos anteriores a la compilación, defina PRE_BUILD_COMMAND. Para ejecutar comandos posteriores a la compilación, defina POST_BUILD_COMMAND.

En el ejemplo siguiente se especifican las dos variables para una serie de comandos, separados por comas.

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"

Para obtener más variables de entorno para personalizar la automatización de compilaciones, consulte la configuración de Oryx.

Para más información sobre cómo se ejecuta App Service y se compilan aplicaciones de Node.js en Linux, consulte la documentación de Oryx sobre cómo se detectan y se compilan las aplicaciones de Node.js.

Configurar el servidor Node.js

Los contenedores de Node.js se suministran con PM2, un administrador de procesos de producción. Puede configurar la aplicación para que se inicie con PM2, con NPM o con un comando personalizado.

Herramienta Propósito
Ejecutar con PM2 Recomendado: uso en producción o ensayo. PM2 proporciona una plataforma de administración de aplicaciones de servicio completo.
Ejecutar npm start Solo en entornos de desarrollo.
Ejecutar un comando personalizado Entornos de desarrollo o ensayo.

Ejecutar con PM2

El contenedor inicia automáticamente la aplicación con PM2 cuando se encuentra uno de los archivos comunes de Node.js en el proyecto:

  • bin/www
  • server.js
  • app.js
  • index.js
  • hostingstart.js
  • Uno de los siguientes archivos PM2: process.json y ecosystem.config.js

También puede configurar un archivo de inicio personalizado con las siguientes extensiones:

  • Un archivo .js
  • Un archivo PM2 con la extensión .json, . config.js, .yaml o .yml

Nota

A partir del nodo 14 LTS, el contenedor no inicia automáticamente la aplicación con PM2. Para iniciar la aplicación con PM2, establezca el comando de inicio en pm2 start <.js-file-or-PM2-file> --no-daemon. Asegúrese de usar el argumento --no-daemon porque PM2 debe ejecutarse en primer plano para que el contenedor funcione correctamente.

Para agregar un archivo de inicio personalizado, ejecute el siguiente comando en Cloud Shell:

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

Ejecutar un comando personalizado

App Service puede iniciar la aplicación con un comando personalizado, por ejemplo, un archivo ejecutable como run.sh. Por ejemplo, para ejecutar npm run start:prod, ejecute el siguiente comando en Cloud Shell:

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

Ejecutar npm start

Para iniciar la aplicación con npm start, asegúrese de que haya un script start en el archivo package.json. Por ejemplo:

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

Para utilizar un archivo package.json personalizado en el proyecto, ejecute el siguiente comando en Cloud Shell:

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

Depuración remota

Nota

La depuración remota se encuentra actualmente en versión preliminar.

Puede depurar la aplicación de Node.js de manera remota en Visual Studio Code si la configura para ejecutar con PM2, excepto cuando se ejecuta con una extensión .config.js, .yml o .yaml.

En la mayoría de los casos, no es necesaria ninguna configuración adicional para la aplicación. Si la aplicación se ejecuta con un archivo process.json (predeterminado o personalizado), debe tener una script propiedad en la raíz JSON. Por ejemplo:

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

Para configurar Visual Studio Code para la depuración remota, instale la extensión App Service. Siga las instrucciones que aparecen en la página de la extensión e inicie sesión en Azure en Visual Studio Code.

En el Explorador de Azure, busque la aplicación que desea depurar, haga clic en ella y seleccione Start Remote Debugging (Iniciar depuración remota). Haga clic en para habilitarla para la aplicación. App Service inicia un proxy de túnel y conecta el depurador. A continuación, puede realizar solicitudes a la aplicación y ver al depurador detenerse en los puntos de interrupción.

Una vez que finalice la depuración, detenga el depurador seleccionando Desconectar. Cuando se le solicite, debe hacer clic en para deshabilitar la depuración remota. Para deshabilitarla más adelante, haga clic en su aplicación de nuevo en el explorador de Azure y seleccione Disable Remote Debugging (Deshabilitar la depuración remota).

Acceso a variables de entorno

En App Service, puede establecer la configuración de la aplicación fuera del código de la aplicación. Luego puede acceder a ellas mediante el patrón estándar de Node.js. Por ejemplo, para acceder a una configuración de una aplicación denominada NODE_ENV, use el código siguiente:

process.env.NODE_ENV

Ejecutar Grunt, Bower o Gulp

De manera predeterminada, la automatización de compilaciones de App Service ejecuta npm install --production cuando reconoce que una aplicación de Node.js se implementa a través de Git o a través de implementación zip con la automatización de compilaciones habilitada. Si la aplicación requiere alguna de las herramientas de automatización más populares, como Grunt, Bower o Gulp, deberá suministrar un script de implementación personalizado para ejecutarla.

Para habilitar que el repositorio ejecute estas herramientas, deberá agregarlas a las dependencias en el archivo package.json. Por ejemplo:

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

Desde una ventana de terminal local, cambie el directorio a la raíz del repositorio y ejecute los siguientes comandos:

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

La raíz del repositorio ahora tiene dos archivos adicionales: .deployment y deploy.sh.

Abra deploy.sh y busque la sección Deployment, que tiene el siguiente aspecto:

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

En esta sección termina con la ejecución de npm install --production. Agregue la sección de código que necesita para ejecutar la herramienta necesaria al final de la sección Deployment:

Consulte un ejemplo en la muestra de MEAN.js, donde el script de implementación también ejecuta un comando npm install personalizado.

Bower

Este fragmento de código ejecuta 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

Este fragmento de código ejecuta 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

Este fragmento de código ejecuta grunt.

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

Detección de sesión de HTTPS

En App Service, la terminación de TLS/SSL se produce en los equilibradores de carga de red, por lo que todas las solicitudes HTTPS llegan a la aplicación como solicitudes HTTP sin cifrar. Si su aplicación lógica necesita comprobar si las solicitudes de usuario están cifradas, inspeccione el encabezado X-Forwarded-Proto.

Los marcos web más usados le permiten acceder a la información de X-Forwarded-* en el patrón de aplicación estándar. En Express, puede usar trust proxy. Por ejemplo:

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

Acceso a los registros de diagnóstico

Para acceder a los registros de la consola generados desde el código de la aplicación en App Service, active el registro de diagnósticos, para lo que debe ejecutar el siguiente comando en Cloud Shell:

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

Los valores posibles de --level son: Error, Warning, Info y Verbose. Todos los niveles incluyen el nivel anterior. Por ejemplo: Error incluye solo los mensajes de error, mientras que Verbose incluye todos los mensajes.

Una vez que se activa el registro de contenedor, ejecute el siguiente comando para ver la transmisión del registro:

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

Si no ve los registros de la consola de inmediato, vuelve a comprobarlo en 30 segundos.

Nota

También puede inspeccionar los archivos de registro desde el explorador en https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Para detener el streaming del registro en cualquier momento, escriba Ctrl+C.

Puede acceder a los registros de consola generados desde dentro del contenedor.

En primer lugar, active el registro de contenedores mediante la ejecución del siguiente comando:

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

Reemplace <app-name> y <resource-group-name> por los nombres adecuados para su aplicación web.

Una vez que se active el registro de contenedor, ejecute el siguiente comando para ver el flujo del registro:

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

Si no ve los registros de la consola de inmediato, vuelve a comprobarlo en 30 segundos.

Para detener el streaming de registro en cualquier momento, escriba Ctrl+C.

Los archivos de registro también se pueden inspeccionar en un explorador en https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Supervisión con Application Insights

Application Insights permite supervisar el rendimiento, las excepciones y el uso de la aplicación sin realizar cambios en el código. Para asociar el agente de App Insights, vaya a la aplicación web en el portal y seleccione Application Insights en Configuración y elija Activar Application Insights. A continuación, seleccione un recurso de App Insights existente o cree uno. Por último, seleccione Aplicar en la parte inferior. Para instrumentar la aplicación web con PowerShell, consulte estas instrucciones.

Este agente supervisará su aplicación de Node.js del lado servidor. Para supervisar el código JavaScript del lado cliente, agregue el SDK de JavaScript al proyecto.

Para más información, consulte las notas de la versión de la extensión de Application Insights.

Solución de problemas

Cuando una aplicación de Node.js en funcionamiento se comporta de manera diferente en App Service o genera errores, intente lo siguiente:

  • Acceso a la secuencia de registros.
  • Pruebe la aplicación localmente en modo de producción. App Service ejecuta las aplicaciones de Node.js en el modo de producción, por lo que deberá asegurarse de que el proyecto funciona según lo previsto en modo de producción localmente. Por ejemplo:
    • En función de su archivo package.json, pueden instalarse distintos paquetes para el modo de producción (dependencies frente a devDependencies).
    • Algunas plataformas web pueden implementar archivos estáticos de forma diferente en modo de producción.
    • Algunas plataformas web pueden usar scripts de inicio personalizados cuando se ejecutan en modo de producción.
  • Ejecute la aplicación en App Service en el modo de desarrollo. Por ejemplo, en MEAN.js, puede establecer la aplicación en modo de desarrollo en tiempo de ejecución estableciendo la configuración de aplicación NODE_ENV.

No tiene permiso para ver este directorio o esta página

Después de implementar el código de Node.js en una aplicación nativa de Windows en App Service, es posible que vea el mensaje You do not have permission to view this directory or page. en el explorador al ir a la dirección URL de la aplicación. Lo más probable es que se deba a que no tiene un archivo web.config (vea la plantilla y un ejemplo).

Si implementa los archivos mediante Git, o mediante implementación ZIP con la automatización de compilación habilitada, el motor de implementación genera automáticamente un archivo web.config en la raíz web de la aplicación (%HOME%\site\wwwroot) si se cumple alguna de las condiciones siguientes:

  • La raíz del proyecto tiene un archivo package.json que define un script start que contiene la ruta de acceso de un archivo de JavaScript.
  • La raíz del proyecto tiene un archivo server.js o app.js.

El archivo web.config generado se ajusta al script de inicio detectado. En otros métodos de implementación, agregue este archivo web.config manualmente. Asegúrese de que el archivo tiene el formato correcto.

Si usa la implementación ZIP (por medio de Visual Studio Code, por ejemplo), asegúrese de habilitar la automatización de compilación, ya que no está habilitada de manera predeterminada. az webapp up usa la implementación ZIP con la automatización de compilación habilitada.

robots933456 en registros

Puede ver el mensaje siguiente en los registros del contenedor:

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

Puede omitir este mensaje sin problemas. /robots933456.txt es una ruta de acceso de la dirección URL ficticia que utiliza App Service para comprobar si el contenedor es capaz de atender las solicitudes. Una respuesta 404 simplemente indica que la ruta de acceso no existe, pero permite a App Service saber que el contenedor está en buen estado y listo para responder a las solicitudes.

Pasos siguientes

O consulte estos recursos adicionales:

Variables de entorno y configuración de la aplicación en Azure App Service