Compartilhar via

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

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

本文介绍关键概念,并为部署到应用服务的 Node.js 开发人员提供说明。 如果从未使用过 Azure 应用服务,请先完成 Node.js 快速入门 MongoDB 教程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 版本。

应用服务中的过时运行时将如何处理?

维护组织弃用过时的运行时,或者其存在重大安全漏洞。 因此,将从门户中的创建和配置页面中删除它们。 当门户中隐藏了过时的运行时后,任何仍使用该运行时的应用程序都会继续运行。

如要创建一个运行时版本过时但尚未在门户中显示的应用程序,可以使用 Azure CLI、ARM 模板或者 Bicep 来实现。 通过这些部署替代方法,可以创建已在门户中移除的但仍受支持的弃用运行时。

如果从应用服务平台完全删除运行时,Azure 订阅所有者会在删除之前收到电子邮件通知。

设置端口号

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

在 Windows 上的应用服务中,Node.js 应用是通过 IISNode托管的,你的 Node.js 应用应侦听 process.env.PORT 变量中指定的端口。 以下示例演示如何在简单的 Express 应用中设置端口:

应用服务在 Node.js 容器中设置环境变量 PORT ,并将传入请求转发到该端口号的容器。 若要接收请求,应用应侦听变量中指定的 process.env.PORT 端口。 以下示例演示如何在简单的 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}`)
})

自定义生成自动化

如果使用 Git 或 启用了生成自动化的 zip 包部署应用,应用服务生成自动化将完成以下步骤:

  1. 运行自定义脚本(如果由 PRE_BUILD_SCRIPT_PATH该脚本指定)。
  2. 不带任何标志运行 npm install 。 此步骤包括 npm preinstallpostinstall 脚本,还安装 devDependencies
  3. 如果在 npm run build 文件中指定了生成脚本,请运行该脚本。
  4. 如果在 npm run build:azurebuild:azure 文件中指定了脚本,请运行该脚本。
  5. 运行自定义脚本(如果由 POST_BUILD_SCRIPT_PATH该脚本指定)。

注意

npm 文档中所述,名为 prebuildpostbuild 的脚本分别在 build 之前和之后运行(如果已指定)。 分别命名 preinstall 和运行之前和 postinstall 之后 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、WITH 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)。例如,若要运行 npm run start:prod,请在 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 中远程调试 Node.js 应用,但使用 .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 部署或通过启用了npm install --production Zip 部署时运行的。 如果你的应用需要任何常用的自动化工具(例如 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 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 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 秒内再次检查。

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

URL 重写

在适用于 Linux 的 Azure 应用服务上部署 Node.js 应用时,可能需要直接在应用程序内处理 URL 重写。 此配置特别适用于确保将特定 URL 模式重定向到正确的终结点,而无需依赖 Web 服务器配置。 可通过多种方式在 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 添加到项目

有关详细信息,请参阅 在适用于 .NET 的 Azure 应用服务、Node.js、Python 和 Java 应用程序中启用应用程序监视

疑难解答

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

  • 访问日志流
  • 在生产模式下,在本地测试应用。 应用服务在生产模式下运行 Node.js 应用,因此需要确保项目在生产模式下按预期在本地运行。 例如:
    • 可以为生产模式安装不同的程序包(dependencies),具体取决于你的 package.jsondevDependencies
    • 某些 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 根目录中自动生成 web.config 文件(%HOME%\site\wwwroot如果满足以下条件之一):

  • 项目根目录包含一个 package.json 文件,该文件定义包含 start JavaScript 文件路径的脚本。
  • 项目根目录包含 server.jsapp.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 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。