Node.js 应用必须与所有必需的 npm 依赖项一起部署。 应用服务部署引擎会在你部署 Git 存储库或部署启用了生成自动化的 Zip 包时自动运行 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 --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="~24"
说明
此示例使用推荐的波形符语法来针对应用服务上 Node.js 24 运行时的最新可用版本。
由于运行时由平台定期修补和更新,因此不建议以特定的次要版本/修补程序为目标。 由于潜在的安全风险,这些版本不能保证可用。
说明
应在项目的 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|24-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 包部署应用,应用服务生成自动化将完成以下步骤:
- 如果
PRE_BUILD_SCRIPT_PATH指定了该脚本,则运行自定义脚本。 - 运行
npm install时不带任何选项。 此步骤包括 npmpreinstall和postinstall脚本,还安装devDependencies。 - 如果在 package.json 文件中指定了构建脚本,请运行
npm run build。 - 如果在 package.json 文件中指定了
build:azure脚本,请运行npm run build:azure。 - 如果已由
POST_BUILD_SCRIPT_PATH指定,则运行自定义脚本。
说明
如 npm 文档中所述,如果已指定,名为 prebuild 和 postbuild 的脚本分别在 build 之前和之后运行。 名为 preinstall 和 postinstall 的脚本分别在 install 之前和之后运行。
PRE_BUILD_COMMAND 和 POST_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 配置。
有关 App Service 如何在 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 或 .yml 的 PM2 文件
说明
在使用 Node.js 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 部署或通过启用了构建自动化的 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 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 会话
在应用服务中,TLS/SSL 终止发生在网络负载均衡器上,因此所有 HTTPS 请求都以未加密的 HTTP 请求的形式到达应用。 如果应用逻辑需要检查用户请求是否已加密,请检查 X-Forwarded-Proto 标头。
使用常用 Web 框架可以在标准应用模式中访问 X-Forwarded-* 信息。 在 Express 中,你可以使用 trust proxies。 例如:
app.set('trust proxy', 1)
...
if (req.secure) {
// Do something when HTTPS is used
}
访问诊断日志
若要访问应用服务中应用程序代码内部生成的控制台日志,请在 Cloud Shell 中运行以下命令来启用诊断日志记录:
az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose
可能的值为 --levelError、 Warning、 Info和 Verbose。 每个后续级别都包括前一级别的内容。 例如, Error 仅包含错误消息。
Verbose 包括所有消息。
启用诊断日志记录后,运行以下命令以查看日志流:
az webapp log tail --resource-group <resource-group-name> --name <app-name>
如果未立即显示控制台日志,请在 30 秒内再次检查。
若要随时停止日志流式处理,请选择 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 应用,因此需要确保项目在本地的生产模式下能够按预期运行。 例如:
- 根据你的 package.json,生产模式下安装的软件包可能会不同(
dependencies与devDependencies)。 - 某些 Web 框架在生产模式下可能会以不同的方式部署静态文件。
- 在生产模式下运行时,某些 Web 框架可能会使用自定义的启动脚本。
- 根据你的 package.json,生产模式下安装的软件包可能会不同(
- 在开发模式下,在 App Service 中运行你的应用。 例如,在 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.js 或 app.js 其中之一文件。
生成的 web.config 文件是针对检测到的启动脚本定制的。 对于其他部署方法,请手动添加 web.config 文件。 请确保文件格式正确。
如果你使用 ZIP 部署(例如通过 Visual Studio Code 或 az webapp deploy),务必启用构建自动化。 默认情况下不启用此功能。
忽略日志中的 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”错误响应指示路径不存在,它向应用服务发出信号,指出容器正常且已准备好响应请求。