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

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

本指南为在应用服务中进行部署的 Node.js 开发人员提供了重要概念和说明。 如果从未使用过 Azure 应用服务,请先按照 Node.js 快速入门操作。

显示 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 --os windows | 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 --os linux | grep NODE

设置 Node.js 版本

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

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 应用应侦听 process.env.PORT 变量中指定的端口。 以下示例演示如何在一个简单的快速应用中执行此操作:

应用服务在 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 文档中所述,名为 prebuildpostbuild 的脚本分别在 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 start 或通过自定义命令启动。

工具 目的
通过 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 "<filename-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 应用是通过 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 示例中的示例,其中的部署脚本也运行自定义 npm install 命令。

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> --docker-container-logging filesystem --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 中检查日志文件。

URL 重写

在适用于 Linux 的 Azure 应用服务上部署 Node.js 应用时,可能需要直接在应用程序内处理 URL 重写。 这对于确保在不依赖 Web 服务器配置的情况下将特定 URL 模式重定向到正确的终结点尤为有用。 可通过多种方式在 Node.js 中完成 URL 重写。 其中一个例子是通过 express-urlrewrite 包。

使用 Application Insights 进行监视

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

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

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

疑难解答

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

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

你无权查看此目录或页面

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

如果你使用 Git 部署文件,或者使用启用了生成自动化的 ZIP 部署,那么在满足以下条件之一时,部署引擎会在应用的 Web 根目录 (%HOME%\site\wwwroot) 中自动生成 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 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。

后续步骤

或者参阅其他某些资源:

环境变量和应用设置参考