为 Azure 应用服务配置 Node.js 应用Configure a Node.js app for Azure App Service

Node.js 应用必须与所有必需的 NPM 依赖项一起部署。Node.js apps must be deployed with all the required NPM dependencies. 当你在启用了生成自动化的情况下部署 Git 存储库Zip 包时,应用服务部署引擎会自动为你运行 npm install --productionThe App Service deployment engine automatically runs npm install --production for you when you deploy a Git repository, or a Zip package with build automation enabled. 但是,如果使用 FTP/S 部署你的文件,则需手动上传所需的包。If you deploy your files using FTP/S, however, you need to upload the required packages manually.

本指南为在应用服务中进行部署的 Node.js 开发人员提供了重要概念和说明。This guide provides key concepts and instructions for Node.js developers who deploy to App Service. 若从未使用过 Azure 应用服务,则首先应按照 Node.js 快速入门以及将 Node.js 与 MongoDB 配合使用的教程进行操作。If you've never used Azure App Service, follow the Node.js quickstart and Node.js with MongoDB tutorial first.

显示 Node.js 版本Show Node.js version

若要显示当前的 Node.js 版本,请在 Azure CLI 中运行以下命令:To show the current Node.js version, run the following command in the 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 中运行以下命令:To show all supported Node.js versions, run the following command in the Azure CLI:

az webapp list-runtimes | grep node

若要显示当前的 Node.js 版本,请在 Azure CLI 中运行以下命令:To show the current Node.js version, run the following command in the Azure CLI:

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

若要显示所有受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令:To show all supported Node.js versions, run the following command in the Azure CLI:

az webapp list-runtimes --linux | grep NODE

设置 Node.js 版本Set Node.js version

若要将应用设置为某个受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令,将 WEBSITE_NODE_DEFAULT_VERSION 设置为受支持的版本:To set your app to a supported Node.js version, run the following command in the Azure CLI to set WEBSITE_NODE_DEFAULT_VERSION to a supported version:

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

此设置指定在运行时以及在自动生成应用服务期间自动还原程序包时要使用的 Node.js 版本。This setting specifies the Node.js version to use, both at runtime and during automated package restore during App Service build automation.

备注

应在项目的 package.json 中设置 Node.js 版本。You should set the Node.js version in your project's package.json. 部署引擎在一个单独的进程中运行,该进程包含所有受支持的 Node.js 版本。The deployment engine runs in a separate process that contains all the supported Node.js versions.

若要将应用设置为某个受支持的 Node.js 版本,请在 Azure CLI 中运行以下命令:To set your app to a supported Node.js version, run the following command in the Azure CLI:

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

此设置指定在运行时以及在 Kudu 中自动还原程序包时要使用的 Node.js 版本。This setting specifies the Node.js version to use, both at runtime and during automated package restore in Kudu.

备注

应在项目的 package.json 中设置 Node.js 版本。You should set the Node.js version in your project's package.json. 部署引擎在一个单独的容器中运行,该容器包含所有受支持的 Node.js 版本。The deployment engine runs in a separate container that contains all the supported Node.js versions.

自定义生成自动化Customize build automation

如果在启用生成自动化的情况下使用 Git 或 zip 包部署应用,应用服务生成自动化将按以下顺序完成各个步骤:If you deploy your app using Git or zip packages with build automation turned on, the App Service build automation steps through the following sequence:

  1. 运行 PRE_BUILD_SCRIPT_PATH 指定的自定义脚本。Run custom script if specified by PRE_BUILD_SCRIPT_PATH.
  2. 在没有任何标志的情况下运行 npm install,这将包括 npm preinstallpostinstall 脚本并将安装 devDependenciesRun npm install without any flags, which includes npm preinstall and postinstall scripts and also installs devDependencies.
  3. 如果在 package.json中指定了生成脚本,请运行 npm run buildRun npm run build if a build script is specified in your package.json.
  4. 如果在 package.json中指定了 build:azure 脚本,请运行 npm run build:azureRun npm run build:azure if a build:azure script is specified in your package.json.
  5. 运行 POST_BUILD_SCRIPT_PATH 指定的自定义脚本。Run custom script if specified by POST_BUILD_SCRIPT_PATH.

备注

npm 文档所述,名为 prebuildpostbuild 的脚本分别在 build 之前和之后运行(如果已指定)。As described in npm docs, scripts named prebuild and postbuild run before and after build, respectively, if specified. preinstallpostinstall 分别在 install 之前和之后运行。preinstall and postinstall run before and after install, respectively.

PRE_BUILD_COMMANDPOST_BUILD_COMMAND 是默认为空的环境变量。PRE_BUILD_COMMAND and POST_BUILD_COMMAND are environment variables that are empty by default. 若要运行生成前命令,请定义 PRE_BUILD_COMMANDTo run pre-build commands, define PRE_BUILD_COMMAND. 若要运行生成后命令,请定义 POST_BUILD_COMMANDTo run post-build commands, define POST_BUILD_COMMAND.

以下示例在一系列命令中指定两个以逗号分隔的变量。The following example specifies the two variables to a series of commands, separated by commas.

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 配置For additional environment variables to customize build automation, see Oryx configuration.

有关应用服务如何在 Linux 中运行和生成 Node.js 应用的详细信息,请参阅 Oryx 文档:如何检测和生成 Node.js 应用For more information on how App Service runs and builds Node.js apps in Linux, see Oryx documentation: How Node.js apps are detected and built.

配置 Node.js 服务器Configure Node.js server

Node.js 容器附带了 PM2(一个生产流程管理器)。The Node.js containers come with PM2, a production process manager. 你可以将应用配置为以 PM2、NPM 或自定义命令启动。You can configure your app to start with PM2, or with NPM, or with a custom command.

运行自定义命令Run custom command

应用服务可以使用自定义命令(例如 run.sh 之类的可执行文件)启动应用。例如,若要运行 npm run start:prod,请在 Azure CLI 中运行以下命令:App Service can start your app using a custom command, such as an executable like run.sh. For example, to run npm run start:prod, run the following command in the Azure CLI:

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

运行 npm startRun npm start

若要使用 npm start 启动应用,只需确保 start 脚本位于 package.json 文件中即可。To start your app using npm start, just make sure a start script is in the package.json file. 例如:For example:

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

若要在项目中使用自定义 package.json,请在 Azure CLI 中运行以下命令:To use a custom package.json in your project, run the following command in the Azure CLI:

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

通过 PM2 运行Run with PM2

在你的项目中找到常用的 Node.js 文件之一时,容器会自动通过 PM2 启动你的应用:The container automatically starts your app with PM2 when one of the common Node.js files is found in your project:

  • bin/wwwbin/www
  • server.jsserver.js
  • app.jsapp.js
  • index.jsindex.js
  • hostingstart.jshostingstart.js
  • 下述 PM2 文件之一:process.json 和 ecosystem.config.jsOne of the following PM2 files: process.json and ecosystem.config.js

你还可以配置具有以下扩展名的自定义启动文件:You can also configure a custom start file with the following extensions:

  • .js 文件A .js file
  • 扩展名为 .json.config.js.yaml.ymlPM2 文件A PM2 file with the extension .json, .config.js, .yaml, or .yml

若要添加自定义启动文件,请在 Azure CLI 中运行以下命令:To add a custom start file, run the following command in the Azure CLI:

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

远程调试Debug remotely

备注

远程调试功能当前为预览版。Remote debugging is currently in Preview.

如果你将 Node.js 应用配置为通过 PM2 运行,则可以在 Visual Studio Code 中远程调试该应用,但使用 .config.js、.yml 或 .yaml 运行它的情况除外。You can debug your Node.js app remotely in Visual Studio Code if you configure it to run with PM2, except when you run it using a *.config.js, *.yml, or .yaml.

在大多数情况下,你的应用不需要进行额外配置。In most cases, no extra configuration is required for your app. 如果你的应用通过 process.json 文件(默认的或自定义的)运行,则它必须在 JSON 根中具有 script 属性。If your app is run with a process.json file (default or custom), it must have a script property in the JSON root. 例如:For example:

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

若要设置用于远程调试的 Visual Studio Code,请安装应用服务扩展To set up Visual Studio Code for remote debugging, install the App Service extension. 按照扩展页上的说明进行操作,在 Visual Studio Code 中登录到 Azure。Follow the instructions on the extension page and sign in to Azure in Visual Studio Code.

在 Azure 资源管理器中,找到要调试的应用,右键单击该应用,然后选择“启动远程调试”。In the Azure explorer, find the app you want to debug, right-click it and select Start Remote Debugging. 单击“是”为你的应用启用该功能。Click Yes to enable it for your app. 应用服务会启动一个隧道代理并附加调试器。App Service starts a tunnel proxy for you and attaches the debugger. 然后,你可以向应用发出请求,并会看到调试器在断点处暂停。You can then make requests to the app and see the debugger pausing at break points.

完成调试后,通过选择“断开连接”来停止调试器。Once finished with debugging, stop the debugger by selecting Disconnect. 出现提示时,应单击“是”以禁用远程调试。When prompted, you should click Yes to disable remote debugging. 若要在以后禁用它,请在 Azure 资源管理器中再次右键单击你的应用,然后选择“禁用远程调试”。To disable it later, right-click your app again in the Azure explorer and select Disable Remote Debugging.

访问环境变量Access environment variables

在应用服务中,可以在应用代码外部设置应用设置In App Service, you can set app settings outside of your app code. 然后,可以使用标准的 Node.js 模式访问这些设置。Then you can access them using the standard Node.js pattern. 例如,若要访问名为 NODE_ENV 的应用设置,请使用以下代码:For example, to access an app setting called NODE_ENV, use the following code:

process.env.NODE_ENV

运行 Grunt/Bower/GulpRun Grunt/Bower/Gulp

默认情况下,当识别出 Node.js 应用是在启用了生成自动化的情况下通过 Git 或 Zip 部署进行部署时,应用服务生成自动化会运行 npm install --productionBy default, App Service build automation runs npm install --production when it recognizes a Node.js app is deployed through Git or Zip deployment with build automation enabled. 如果你的应用需要任何常用的自动化工具(例如 Grunt、Bower 或 Gulp),你需要提供自定义部署脚本才能运行该应用。If your app requires any of the popular automation tools, such as Grunt, Bower, or Gulp, you need to supply a custom deployment script to run it.

若要使你的存储库能够运行这些工具,需要将它们添加到 package.json 中的依赖项。To enable your repository to run these tools, you need to add them to the dependencies in package.json. 例如:For example:

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

在本地终端窗口中,将目录更改到你的存储库根目录,并运行以下命令:From a local terminal window, change directory to your repository root and run the following commands:

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

你的存储库根目录中现在有两个额外的文件:.deployment 和 deploy.sh。Your repository root now has two additional files: .deployment and deploy.sh.

打开 deploy.sh 并找到 Deployment 节,该节如下所示:Open deploy.sh and find the Deployment section, which looks like this:

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

该节在末尾处运行 npm install --productionThis section ends with running npm install --production. Deployment 节的末尾添加运行必需工具所需的代码节Add the code section you need to run the required tool at the end of the Deployment section:

请参阅 MEAN.js 示例中的示例,其中的部署脚本也运行自定义 npm install 命令。See an example in the MEAN.js sample, where the deployment script also runs a custom npm install command.

BowerBower

此代码片段运行 bower installThis snippet runs 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

GulpGulp

此代码片段运行 gulp imageminThis snippet runs 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

GruntGrunt

此代码片段运行 gruntThis snippet runs grunt.

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

检测 HTTPS 会话Detect HTTPS session

在应用服务中,SSL 终止在网络负载均衡器上发生,因此,所有 HTTPS 请求将以未加密的 HTTP 请求形式访问你的应用。In App Service, SSL termination happens at the network load balancers, so all HTTPS requests reach your app as unencrypted HTTP requests. 如果应用逻辑需要检查用户请求是否已加密,可以检查 X-Forwarded-Proto 标头。If your app logic needs to check if the user requests are encrypted or not, inspect the X-Forwarded-Proto header.

使用常用 Web 框架可以访问采用标准应用模式的 X-Forwarded-* 信息。Popular web frameworks let you access the X-Forwarded-* information in your standard app pattern. Express 中,你可以使用信任代理In Express, you can use trust proxies. 例如:For example:

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

访问诊断日志Access diagnostic logs

若要访问应用服务中的应用程序代码内生成的控制台日志,请在 Azure CLI 中运行以下命令以打开诊断日志记录:To access the console logs generated from inside your application code in App Service, turn on diagnostics logging by running the following command in the Azure CLI:

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

--level 的可能值为:ErrorWarningInfoVerbosePossible values for --level are: Error, Warning, Info, and Verbose. 每个后续级别包括上一个级别。Each subsequent level includes the previous level. 例如:Error 仅包含错误消息,Verbose 则包含所有消息。For example: Error includes only error messages, and Verbose includes all messages.

启用诊断日志记录功能以后,请运行以下命令来查看日志流:Once diagnostic logging is turned on, run the following command to see the log stream:

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

如果没有立即看到控制台日志,请在 30 秒后重新查看。If you don't see console logs immediately, check again in 30 seconds.

备注

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。You can also inspect the log files from the browser at https://<app-name>.scm.chinacloudsites.cn/api/logs/docker.

若要随时停止日志流式处理,请键入 Ctrl+CTo stop log streaming at any time, type Ctrl+C.

可以访问在容器中生成的控制台日志。You can access the console logs generated from inside the container. 首先,请在 Cloud Shell 中运行以下命令,以便启用容器日志记录功能:First, turn on container logging by running the following command in the Cloud Shell:

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

启用容器日志记录功能以后,请运行以下命令来查看日志流:Once container logging is turned on, run the following command to see the log stream:

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

如果没有立即看到控制台日志,请在 30 秒后重新查看。If you don't see console logs immediately, check again in 30 seconds.

备注

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。You can also inspect the log files from the browser at https://<app-name>.scm.chinacloudsites.cn/api/logs/docker.

若要随时停止日志流式处理,请键入 Ctrl+CTo stop log streaming at any time, type Ctrl+C.

疑难解答Troubleshooting

如果运行中的 Node.js 应用在应用服务中的行为不同或有错误,请尝试执行以下操作:When a working Node.js app behaves differently in App Service or has errors, try the following:

  • 访问日志流Access the log stream.
  • 在生产模式下,在本地测试应用。Test the app locally in production mode. 应用服务在生产模式下运行 Node.js 应用,因此需要确保项目在生产模式下按预期在本地运行。App Service runs your Node.js apps in production mode, so you need to make sure that your project works as expected in production mode locally. 例如:For example:
    • 可以为生产模式安装不同的程序包(dependenciesdevDependencies),具体取决于你的 package.json。Depending on your package.json, different packages may be installed for production mode (dependencies vs. devDependencies).
    • 某些 Web 框架可以在生产模式下通过各种方式部署静态文件。Certain web frameworks may deploy static files differently in production mode.
    • 在生产模式下运行时,某些 Web 框架可能会使用自定义的启动脚本。Certain web frameworks may use custom startup scripts when running in production mode.
  • 在开发模式下,在应用服务中运行你的应用。Run your app in App Service in development mode. 例如,在 MEAN.js 中,可以通过设置 NODE_ENV 应用设置在运行时中将应用设置为开发模式。For example, in MEAN.js, you can set your app to development mode in runtime by setting the NODE_ENV app setting.

日志中的 robots933456robots933456 in logs

你可能会在容器日志中看到以下消息:You may see the following message in the container logs:

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

可以放心忽略此消息。You can safely ignore this message. /robots933456.txt 是一个虚拟 URL 路径,应用服务使用它来检查容器能否为请求提供服务。/robots933456.txt is a dummy URL path that App Service uses to check if the container is capable of serving requests. 404 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。A 404 response simply indicates that the path doesn't exist, but it lets App Service know that the container is healthy and ready to respond to requests.

后续步骤Next steps