Internet Information Server (IIS) and node.js in Producton = iisnode

We, here at Simply Migrate are geeks at heart. We’re solving the hard problems, so you, our amazing customers don’t have to.

On top of our enterprise focused product, we have a consumer orientated one, which allows us to migrate your cloud based files between different providers. In our sources and targets we options for providers such as; OneDrive, OneDrive for Business, Dropbox, Box and many others.

Background

We’re typically a Microsoft orientated stack, basing our code base on .NET, ASP.NET and now .NET Core. We based these decisions on the domain issue at hand. Part of working in such a manor, we selected the best tool of choice in our view, for the problem at hand. We also selected node.js to run parts of our consumer offering.

node.js delivers the performance, the extensibility and ease of use that we require to get to market quickly. We debated on what platform to run node.js on and based on the stability, performant and fantastic work done by Tomasz Janczuk we opted for iisnode.

What is iisnode?

iisnode is a native IIS module that allows hosting of node.js applications in IIS on Windows. If you would like to know some of the awesome benefits you get running iisnode please have a look at the offical wiki – https://github.com/tjanczuk/iisnode/wiki#benefits.

Installing

Pre-requisites

Our pre-requistes for the install will be as follows, as of writing the following versions were used;

Install

The install is pretty straight forward for each component. You can simply go through each pre-requisites native UI or have it scripted.

  • Install IIS via your preferred method. PowerShell or via Server Manager.
  • Install IIS URL Rewrite extension via the Web Platform Install UI or WebPICMD.
  • Install node.js from your binary download.
  • Install iisnode from your binary download.

Configure

When we first started to use iisnode, I must admit there was some trial and error in getting it up and running. Hopefully we can list some of the caveats that we encountered so you don’t run into the same issues.

IIS

For testing purposes, we’ll use Default Web Site in IIS to perform all our steps. You’ll of course want to create your own site, with your own Application Pool, Application Pool Identity and a unique disk location.

iisnode

By default iisnode installs to ‘C:\Program Files\iisnode‘ on x64 systems. Under the install location there are some fantastic examples located in ‘www‘. You’ll notice that there is a ‘setupsamples.bat‘ batch file. Lets run it.

  • setupsamples.bat will create a node Virtual Directory in your Default Web Site.

  • As with all new configurations a simple Hello World is a great first step in ensuring everything is wired up correctly.

  • Select the helloworld link to check that IIS + node.js + iisnode are playing nice.
  • If all is well then you will be presented with Hello, world! helloworld sample; iisnode version is 0.2.21, node version is v6.8.0.

One cool feature of iisnode, is that you can see your node.js requests being passed through for any troubleshooting or debugging. You’d have to this disabled in Production of course.

  • Try it for yourself, open up the logging link in the samples.

  • Hit hello.js in the sample first of all to generate a log entry.
  • Go back and select the logs option to view a rendered log entry

More iisnode

The above steps are there to validate your install. But of course you want to run it in anger in Production and this is where the fun starts.

iisnode is configured usnig .yml (https://en.wikipedia.org/wiki/YAML) files, iisnode.yml specifically.

iisnode will read the iisnode.yml file on each user request. So if you’re require to quickly debug some issue on the server side you can change any one of the values and the next request will have it applied.

One note of interest in the iisnode.yml file is the nodeProcessCountPerApplication. This controls the number of node process that iisnode should run. You have fantastic tools like nodemon to or the inbuilt fork() to run a web farm, but from our testing and reports in the wild we opted for iisnode due to a higher level of stability.

If you’re going to be spinning up extra node process, ensure you have a session state database running behind the scenes to keep your user sessions in a valid state. We’ve found that the mssql-sesssion-store (https://www.npmjs.com/package/mssql-session-store) npm works very well if you’re using the Microsoft stack.

Rewrite

Once you have iisnode up and running the next challenge is implementing re-write rules so your application is functioning correctly.

The iisnode handler requires and entry point for the application, in this example use case it’ll be app.js.

In the rewrite rules you’ll want to define;

  • http to https redirects. Unless you’re running a load balancer/proxy which does this for you.
  • Any domain rewrites. www to domain.com or vice versa.
  • Passing any static content through.
  • Configuring your debugging options.

This was probably the most challenging part of getting iisnode up and running. There wasn’t to many concise examples out there so we’ve done the hard work for you. He’s a working example you might want to use.

<?xml version="1.0" encoding="UTF-8"?>
<rewrite>
  <rules>
    <!-- Rewrite all http requests to https -->
    <rule name="Redirect HTTP to HTTPS" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="^OFF$" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
    </rule>
    <!-- Rewrite all www requests to .domain -->
    <rule name="Redirect www.domain.com to domain.com" patternSyntax="ECMAScript" stopProcessing="true">
      <match url=".*" />
      <conditions>
        <add input="{HTTP_HOST}" pattern="^www.domain.com$" />
      </conditions>
      <action type="Redirect" url="https://domain.com/{R:0}" />
    </rule>
    <!-- Don't interfere with requests for logs -->
    <rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
      <match url="^[a-zA-Z0-9_\-]+\.js\.logs\/\d+\.txt$" />
    </rule>
    <!-- Do not interfere with requests for node-inspector debugging -->
    <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
      <match url="^app.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="app.js" />
    </rule>
  </rules>
</rewrite>

Conclusion

We hope you find this post informative on how to get the most out of node.js with your IIS deployments.

About

Simply Migrate makes your enterprise migrations simple. Our enterprise tool does all the hard work so that you can focus on what is most important, your customers.

Our consumer product will will migrate all your cloud based files between a large number of providers.

For more information please get in on our “How can we help?” widget or drop us a mail on hello@simplymigrate.com.

No Comments

Be the first to start a conversation

Leave a Comment