为 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 | 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 中运行以下命令,将 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 包部署应用,应用服务生成自动化将按以下顺序完成各个步骤:
- 运行
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 配置。
有关应用服务如何在 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 或 .yml 的 PM2 文件
注意
从 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 应用是在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 示例中的示例,其中的部署脚本也运行自定义 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
的可能值为:Error
、Warning
、Info
和 Verbose
。 每个后续级别包括上一个级别。 例如: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,可以监视应用程序的性能、异常和使用情况,而无需进行任何代码更改。 若要附加 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_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 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。
后续步骤
或者参阅其他某些资源: