Overview

I was recently given a task to deploy Node application using Azure Web App within Azure App Service Plan. It seems that most documentation for this scenario is assuming you will use GitHub repository as a source for your deployment pipeline. For me that wasn’t a case, so now I wanted to share how this task can be achieved and tested from scratch. In this article, I’m assuming you’re using both Windows for your local development and Windows App Service Plan.

Prepare cloud environnement and select Node version

At this point, I’m assuming you’ve already created empty Web App within App Service Plan. Firstly, let’s configure Node version which this application will use.

At any point, if you want to check what version of node your application is using, Kudu terminal is a convenient way to do it. Navigate to https://{application_name}.scm.azurewebsites.net/ and open PowerShell console from Debug console menu item.

Type in the console:

node --version

Output will be similar to this:

PS D:\home> node --version 
v6.9.1 
PS D:\home>

There are a few ways to specify your node version. Probably the easiest way is to add or modify WEBSITE_NODE_DEFAULT_VERSION app setting in Application Settings blade:

App Setting blade

Please note:

If you set your version to either non-existing one or version which is not supported by Web Application, Azure will pick some other version as default. Always make sure that the version you’ve selected is supported, simply rechecking the version in the console.

There’s quite an easy way to check which versions are supported. In Kudu PowerShell console type:

cd "D:\Program Files (x86)\nodejs"

This will show you the directory with all versions available. If you want to use a different version, you can follow this article from Microsoft link to do so.

Prepare and run your application locally

Create application

Our application will be very basic. On your local machine, please create new directory and add server.js file with this content :

 var http = require('http');
 http.createServer(function(req,res) {
   res.end('Hello from Node Application');
 }).listen(process.env.PORT || 3000);

The application will listen either on port defined by PORT variable (this will be used on Azure). If not provided this will default to 3000 port.

Normally, you’d type

node .\server.js

to run this application. But we want to run this application in the same way it will be run on Azure, which is IIS running with IISNode module. You can check IISNode GitHub project here.

Get IIS configuration

The first thing we need to do is to add web.config file to our directory. This will contain all configuration needed for IIS to know how to run your application.

** Please note:**

If you select GitHub as your application source, this file will be created for you automatically.

Luckily, the default web.config file provided by Project Kudu should be enough for most projects to run them without any troubles. More details are available on this page

Create web.config and add default configuration. Make sure to check the Project Kudu page first for the latest version, but that’s what I’ve used for this article:

<?xml version="1.0" encoding="utf-8"?>
<!--
     This configuration file is required if iisnode is used to run node processes behind
     IIS or IIS Express.  For more information, visit:
 https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->

<configuration>
  <system.webServer>
    <!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
    <webSocket enabled="false" />
    <handlers>
      <!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
      <add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
    </handlers>
    <rewrite>
      <rules>
        <!-- Do not interfere with requests for node-inspector debugging -->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="^server.js\/debug[\/]?" />
        </rule>

        <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}"/>
        </rule>

        <!-- All other URLs are mapped to the node.js site entry point -->
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
          </conditions>
          <action type="Rewrite" url="server.js"/>
        </rule>
      </rules>
    </rewrite>
    
    <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
    <security>
      <requestFiltering>
        <hiddenSegments>
          <remove segment="bin"/>
        </hiddenSegments>
      </requestFiltering>
    </security>

    <!-- Make sure error responses are left untouched -->
    <httpErrors existingResponse="PassThrough" />

    <!--
      You can control how Node is hosted within IIS using the following options:
        * watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
        * node_env: will be propagated to node as NODE_ENV environment variable
        * debuggingEnabled - controls whether the built-in debugger is enabled

      See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
    -->
    <!--<iisnode watchedFiles="web.config;*.js"/>-->
  </system.webServer>
</configuration>

Most importantly, this line defines entrypoint for your application:

      <add name="iisnode" path="server.js" verb="*" modules="iisnode"/>

Now that we have our configuration, we are ready to run it.

Run application locally using IIS

Firstly you need to make sure you’ve IIS installed with both IIS Management Console and ASP.NET 4.6 features. IIS feature

Additionally, you need:

Now you can add your website in IIS. While adding binding, make sure to use the same port which is defined in your node application. In our example, it’s port 3000. Binding

Now you should be able to navigate to http://localhost:3000 and see the same application again. Although it seems like much more complicated way to run your application locally, it gives you some benefits:

  • you have the same, consistent way to run and test your application both locally and on Azure.
  • if you will ever need to change web.config rewrite rules, you can test that locally too.

Deployment

There are obviously multiple ways for you to deploy your application to Azure. In this blog post, we’ll take the simplest way possible. In Kudu PowerShell console navigate to: D:\home\site\wwwroot directory. Remove default hostingstart.html file and drag and drop both server.js and web.config files to that directory.

Your structure should be:

Directory: D:\home\site\wwwroot 
Mode LastWriteTime Length Name 
---- ------------- ------ ---- 
-a--- 7/22/2017 8:53 PM 151 server.js 
-a--- 7/22/2017 8:53 PM 2567 web.config 

Congratulations, your application should be up and running now. Navigate to https://{application_name}.azurewebsites.net/.

Port environment variable

The one thing which could be confusing at this point is process.env.port variable. Let’s use Kudu to find out the current value for this variable.

In Kudu site, navigate to Process Explorer, right click on node.exe process and select Properties. You should see something similar to: Kudu env

You could expect that Port value will be simply - an integer number. It occurs that Azure is using Named Piped communication internally, more details here.

If you try to use an integer value for your server listener port application will simply fail to run.

Conclusion

It’s definitely beneficial to know some key elements which are needed for Node application deployment. Additionally, running your application locally in the same way as on Azure should help you with quicker and more confident development.