为 Azure 应用服务配置 Node.js 应用

Node.js 应用必须与所有必需的 NPM 依赖项一起部署。 在启用了生成自动化的情况下部署 npm install --productionZip 包时,应用服务部署引擎会自动运行 npm install --production。 但是,如果使用 FTP/S 部署你的文件,则需手动上传所需的包。

本指南为在应用服务中进行部署的 Node.js 开发人员提供了重要概念和说明。 若从未使用过 Azure 应用服务,则首先应按照 Node.js 快速入门以及将 Node.js 与 MongoDB 配合使用的教程进行操作。

显示 Node.js 版本

若要显示当前的 Node.js 版本,请在 Azure CLI 中运行以下命令:

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

若要显示所有受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令:

az webapp list-runtimes | grep node

若要显示当前的 Node.js 版本,请在 Azure CLI 中运行以下命令:

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

若要显示所有受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令:

az webapp list-runtimes --linux | grep NODE

设置 Node.js 版本

若要将应用设置为某个受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令,将 设置为受支持的版本:

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

注意

此示例使用建议的“波浪号语法”来定位应用服务上 Node.js 16 运行时的最新可用版本。

由于平台会定期修补和更新运行时,因此不建议针对特定的次要版本/补丁,因为由于存在潜在的安全风险,不能保证这些版本/补丁可用。

注意

应在项目的 package.json 中设置 Node.js 版本。 部署引擎在一个单独的进程中运行,该进程包含所有受支持的 Node.js 版本。

若要将应用设置为某个受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令:

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

此设置指定在运行时以及在 Kudu 中自动还原程序包时要使用的 Node.js 版本。

注意

应在项目的 package.json 中设置 Node.js 版本。 部署引擎在一个单独的容器中运行,该容器包含所有受支持的 Node.js 版本。

获取端口号

Node.js 应用需要侦听正确的端口才能接收传入的请求。

在 Windows 上的应用服务中,Node.js 应用是通过 IISNode托管的,你的 Node.js 应用应侦听 变量中指定的端口。 以下示例演示如何在一个简单的快速应用中执行此操作:

应用服务在 Node.js 容器中设置环境变量 PORT,并在该端口号将传入请求转发到你的容器。 若要接收请求,你的应用应该使用 process.env.PORT 侦听该端口。 以下示例演示如何在一个简单的快速应用中执行此操作:

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

自定义生成自动化

如果在启用了生成自动化的情况下使用 Git 或 zip 包部署应用,应用服务生成自动化将按以下顺序完成各个步骤:

  1. 运行 PRE_BUILD_SCRIPT_PATH 指定的自定义脚本。
  2. 在没有任何标志的情况下运行 npm install,这将包括 npm preinstallpostinstall 脚本并将安装 devDependencies
  3. 如果在 package.json中指定了生成脚本,请运行 npm run build
  4. 如果在 package.json中指定了 build:azure 脚本,请运行 npm run build:azure
  5. 运行 POST_BUILD_SCRIPT_PATH 指定的自定义脚本。

注意

npm 文档所述,名为 postbuild 的脚本分别在 build 之前和之后运行(如果已指定)。 preinstallpostinstall 分别在 install 之前和之后运行。

PRE_BUILD_COMMANDPOST_BUILD_COMMAND 是默认为空的环境变量。 若要运行生成前命令,请定义 PRE_BUILD_COMMAND。 若要运行生成后命令,请定义 POST_BUILD_COMMAND

以下示例在一系列命令中指定两个以逗号分隔的变量。

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"

有关用于自定义生成自动化的其他环境变量,请参阅 Oryx 配置

有关应用服务如何在 Linux 中运行和生成 Node.js 应用的详细信息,请参阅 Oryx 文档:如何检测和生成 Node.js 应用

配置 Node.js 服务器

Node.js 容器附带了 PM2(一个生产流程管理器)。 你可以将应用配置为以 PM2、NPM 或自定义命令启动。

工具 目的
通过 PM2 运行 建议 - 在生产或暂存期间使用。 PM2 提供了全方位服务的应用管理平台。
运行 npm start 仅在开发期间使用。
运行自定义命令 在开发或过渡期间使用。

通过 PM2 运行

在你的项目中找到常用的 Node.js 文件之一时,容器会自动通过 PM2 启动你的应用:

  • bin/www
  • server.js
  • app.js
  • index.js
  • hostingstart.js
  • 下述 PM2 文件之一:process.json 和 ecosystem.config.js

你还可以配置具有以下扩展名的自定义启动文件:

  • .js 文件
  • 扩展名为 .json.config.js.yaml.ymlPM2 文件

注意

从 Node 14 LTS 开始,容器不会自动使用 PM2 启动应用。 若要使用 PM2 启动应用,请将启动命令设置为 pm2 start <.js-file-or-PM2-file> --no-daemon。 请务必使用 --no-daemon 参数,因为 PM2 需要在前台运行才能使容器正常工作。

若要添加自定义启动文件,请在 Azure CLI 中运行以下命令:

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

运行自定义命令

“应用服务”可以使用自定义命令(例如,run.sh 之类的可执行文件)启动应用。例如,要运行 ,请在 Azure CLI 中运行以下命令:

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

运行 npm start

若要使用 npm start 启动应用,只需确保 start 脚本位于 package.json 文件中即可。 例如:

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

若要在项目中使用自定义 package.json,请在 Azure CLI 中运行以下命令:

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

远程调试

注意

远程调试功能当前为预览版。

如果你将 Node.js 应用配置为通过 PM2 运行,则可以在 Visual Studio Code 中远程调试该应用,但使用 .config.js、.yml 或 .yaml 运行它的情况除外。

在大多数情况下,你的应用不需要进行额外配置。 如果你的应用通过 process.json 文件(默认的或自定义的)运行,则它必须在 JSON 根中具有 属性。 例如:

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

若要设置用于远程调试的 Visual Studio Code,请安装应用服务扩展。 按照扩展页上的说明进行操作,在 Visual Studio Code 中登录到 Azure。

在 Azure 资源管理器中,找到要调试的应用,右键单击该应用,然后选择“启动远程调试”。 单击“是”为你的应用启用该功能。 应用服务会启动一个隧道代理并附加调试器。 然后,你可以向应用发出请求,并会看到调试器在断点处暂停。

完成调试后,通过选择“断开连接”来停止调试器。 出现提示时,应单击“是”以禁用远程调试。 若要在以后禁用它,请在 Azure 资源管理器中再次右键单击你的应用,然后选择“禁用远程调试”。

访问环境变量

在应用服务中,可以在应用代码外部设置应用设置。 然后,可以使用标准的 Node.js 模式访问这些设置。 例如,若要访问名为 NODE_ENV 的应用设置,请使用以下代码:

process.env.NODE_ENV

运行 Grunt/Bower/Gulp

默认情况下,当识别出 Node.js 应用是在npm install --production的情况下通过 Git 或 Zip 部署进行部署时,应用服务生成自动化会运行 npm install --production。 如果你的应用需要任何常用的自动化工具(例如 Grunt、Bower 或 Gulp),你需要提供自定义部署脚本才能运行该应用。

若要使你的存储库能够运行这些工具,需要将它们添加到 package.json 中的依赖项。例如:

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

在本地终端窗口中,将目录更改到你的存储库根目录,并运行以下命令:

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

你的存储库根目录中现在有两个额外的文件:.deployment 和 deploy.sh。

打开 deploy.sh 并找到 节,该节如下所示:

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

该节在末尾处运行 npm install --production。 在 节的末尾添加运行必需工具所需的代码节:

请参阅 MEAN.js 示例中的示例,其中的部署脚本也运行自定义 命令。

Bower

此代码片段运行 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

此代码片段运行 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

此代码片段运行 grunt

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

检测 HTTPS 会话

在应用服务中,SSL 终止在网络负载均衡器上发生,因此,所有 HTTPS 请求将以未加密的 HTTP 请求形式访问你的应用。 如果应用逻辑需要检查用户请求是否已加密,可以检查 X-Forwarded-Proto 标头。

使用常用 Web 框架可以访问采用标准应用模式的 X-Forwarded-* 信息。 在 Express 中,你可以使用信任代理。 例如:

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

访问诊断日志

若要访问应用服务中的应用程序代码内生成的控制台日志,请在 Azure CLI 中运行以下命令以打开诊断日志记录:

az webapp log config --resource-group <resource-group-name> --name <app-name> --application-logging true --level Verbose

--level 的可能值为:ErrorWarningInfoVerbose。 每个后续级别包括上一个级别。 例如:Error 仅包含错误消息,Verbose 则包含所有消息。

启用诊断日志记录功能以后,请运行以下命令来查看日志流:

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

如果没有立即看到控制台日志,请在 30 秒后重新查看。

注意

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。

若要随时停止日志流式处理,请键入 Ctrl+C

可以访问在容器中生成的控制台日志。

首先,请运行以下命令,以便启用容器日志记录功能:

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

<app-name><resource-group-name> 替换为适合 Web 应用的名称。

启用容器日志记录功能以后,请运行以下命令来查看日志流:

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

如果没有立即看到控制台日志,请在 30 秒后重新查看。

若要随时停止日志流式处理,可键入 CtrlC。

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。

使用 Application Insights 进行监视

利用 Application Insights,可以监视应用程序的性能、异常和使用情况,而无需进行任何代码更改。 若要附加 App Insights 代理,请转到门户中的 Web 应用并选择“设置”下的“Application Insights”,然后选择“打开 Application Insights” 。 接下来,请选择现有的或创建一个新的 App Insights 资源。 最后,选择底部的“应用”。 若要使用 PowerShell 来检测 Web 应用,请参阅这些说明

此代理将会监视服务器端 Node.js 应用程序。 若要监视客户端 JavaScript,请将 JavaScript SDK 添加到项目

有关详细信息,请参阅 Application Insights 扩展发行说明

疑难解答

如果运行中的 Node.js 应用在应用服务中的行为不同或有错误,请尝试执行以下操作:

  • 访问日志流
  • 在生产模式下,在本地测试应用。 应用服务在生产模式下运行 Node.js 应用,因此需要确保项目在生产模式下按预期在本地运行。 例如:
    • 可以为生产模式安装不同的程序包(devDependencies),具体取决于你的 package.json。
    • 某些 Web 框架可以在生产模式下通过各种方式部署静态文件。
    • 在生产模式下运行时,某些 Web 框架可能会使用自定义的启动脚本。
  • 在开发模式下,在应用服务中运行你的应用。 例如,在 MEAN.js 中,可以通过设置 应用设置在运行时中将应用设置为开发模式。

你无权查看此目录或页面

将 Node.js 代码部署到应用服务中的本机 Windows 应用后,导航到应用的 URL 时,可能会在浏览器中看到消息 You do not have permission to view this directory or page.。 这很可能是因为没有 web.config 文件(请参阅模板示例)。

如果你使用 Git 部署文件,或者使用启用了生成自动化的 ZIP 部署,那么在满足以下条件之一时,部署引擎会在应用的 Web 根目录 () 中自动生成 web.config:

  • 你的项目根具有一个 package.json,它定义包含 JavaScript 文件路径的 脚本。
  • 项目根具有 server.js 或 app.js。

生成的 web.config 是根据检测到的启动脚本定制的。 对于其他部署方法,请手动添加此 web.config。 请确保文件格式正确。

如果使用 ZIP 部署(例如,通过 Visual Studio Code),请务必启用生成自动化,因为默认情况下不启用。 az webapp up 使用启用了生成自动化的 ZIP 部署。

日志中的 robots933456

你可能会在容器日志中看到以下消息:

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

可以放心忽略此消息。 /robots933456.txt 是一个虚拟 URL 路径,应用服务使用它来检查容器能否为请求提供服务。 404 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。

后续步骤

或者参阅其他某些资源:

环境变量和应用设置参考