Currently Kudu supports running node.js applications using a single node.js version installed on the machine. This is to add support for running node.js applications using more than one version, and provide a mechanism for the application to choose a particular node.js version to use. The design follows below.
Overview
This is the precedence of mechanisms used to determine the version of node.js for a particular application deployed to Azure Web Sites:
- Explicit nodeProcessCommandLine entry in iisnode.yml
- Explicit version constraint in the "engines" element of package.json
- NODE_VERSION application setting set in the portal (going forward this can be replaced with a first class management portal knob like we have for PHP if we choose so, but we don't think this is a priority)
- "Default" version of node.js which we decide on for every Azure Web Sites release.
The user experience
The lowest level versioning mechanism for node.js in Azure Web Sites which already works today is to deploy a custom node.exe version alongside the application and configure iisnode via web.config or iisnode.yml to use that executable. While this mechanism provides the user with full control over the version of node.js as well as a convenient mechanism to fall back to in advanced scenarios, we do not envision the mainstream of users to employ it for usability reasons.
The key mechanism we want people to use when choosing the node.js engine version for an app running in Azure Web Sites is the established configuration file for node.js applications: package.json. Within it, the already established "engines" element specifies an expression that constrains the node.js version this application requires. For example, one can say "0.6.19" to indicate a particular version, or "0.6.x || > 0.8.1" to indicate either any of the 0.6 versions or a version later than 0.8.1. For more information about the "engines" element in package.json, see "npm help json".
{
"engines": {
"node": "0.8.0"
}
}
If the user does not provide a package.json alongside their application, or if the package.json does not specify any costraints for the node.js version number, Azure Web Sites will always use the default node.js version. The default version of node.js may change over time as the Azure Web Sites plarform revs. One implication of this is that apps that did not explicitly constrain the version of the node.js engine will be over time automatically upgraded to whatever version Azure Web Sites considers "default". This may imply breaking existing applications. There is no mechanism of "pinning" applications that do not have explicit node.js version constraints to the version that was default at the time they were deployed.
If the user provides node.js version constraints within package.json, Azure Web Sites will use the highest node.js version number across the versions pre-installed on the Azure Web Sites platform which satisfies the version constraint. This is the versioning mechanism already implemented in git-azure (https://github.com/tjanczuk/git-azure) for which we received positive feedback from several insiders. For example, if the package.json says "0.6.x || > 0.8.1", and the platform has 0.6.17, 0.6.19, and 0.8.0 installed, we will pick 0.6.19.
If the user does not specify a particular version of node.js using package.json file, they can still do so using the Azure Web Sites management portal by setting the node_version
application setting to a specific semever version, e.g. 0.6.19
.
The setting in the portal is subordinate to the setting in package.json.
Engineering
The WebPI feed that installs node.js components in Azure Web Sites is modified to install a default version of node.js as well as a number of other node.js engines side by side. The prototype of the WebPI feed is at https://github.com/tjanczuk/nodepi/blob/master/nodepi.xml.
The end result of installing several versions of node.js plarform looks like this:
C:\projects\nodepi>dir /s /b "c:\Program Files\nodejs"\node.exe
c:\Program Files\nodejs\node.exe
c:\Program Files\nodejs\0.6.19\node.exe
c:\Program Files\nodejs\0.8.1\node.exe
The version installed in c:\Program Files\nodejs\node.exe
is the default version of node.js. It also provides the npm tool used by Kudu for all node.js applications, regardless of the runtime version they use. The versions of node.js installed in subdirectories of c:\Program Files\nodejs
are all versions available on the Azure Web Sites platform at a given point in time (one of them is the same as the default version).
The Kudu logic is modified to execute a custom (node.js) script during application deployment. The script detects the existence of node.js version constraints in the the package.json file deployed with the application. If the constraint is specified, and if the iisnode.yml
file does not exist or does not contain an explicit nodeProcessCommandLine
entry, it will generate such entry in the iisnode.yml
file. The generated nodeProcessCommandLine
entry will specify the exact path to the maximum node.js engine version installed on the Azure Web Sites platform that satisfies the version constraint of the application (similarly to https://github.com/tjanczuk/git-azure). For example:
nodeProcessCommandLine: "c:\program files\nodejs\0.6.19\node.exe" "c:\program files\iisnode\interceptor.js"
This mechanism ensures that version constraints specified in the package.json file are applied unless the user explicitly specified the node.js command line to run in iisnode.yml
(which is the lowest level versioning mechanism that overrides everything else).
The default web.config
for iisnode is modified to specify the nodeProcessCommandLine
as follows:
"%programfiles%\nodejs\%node_version%\node.exe" ...
If the iisnode.yml
file does not override the nodeProcessCommandLine
setting, this value remains effective for an application. The environment variables are expanded at runtime, which allows for the NODE_VERSION
environment variable specified in the management portal to be effective unless overriden by the package.json
setting or the explicit nodeProcessCommandLine
entry in iisnode.yml.
Note that if the user does not specify NODE_VERSION
in the app settings in the portal, the effective nodeProcessCommandLine
becomes
"%programfiles%\nodejs\\node.exe" ...
which basically points to the "default" version of node.js for a given release of Azure Web Sites.