IIS Hosting Nodejs Application

Adrian Jenkins
6 min readFeb 8, 2023

Prerequisites:

  • Internet Information Services (IIS)

Default installation through Server Manager will suffice for this tutorial.

iisnode is a native IIS module that allows hosting of node.js applications in IIS on Windows. It comes with a lot of benefits, including process management, scalability on multi-core servers, integrated debugging and many more.

Prerequisites for using iisnode are Windows Vista, Windows 7, Windows 8, Windows Server 2008, or Windows Server 2012; IIS 7.x with IIS Management Tools and ASP.NET; WebSocket functionality requires IIS 8.x on Windows 8 or Windows Server 2012; URL rewrite module for IIS; and the latest node.js build for Windows.

After installing the “.msi” it will add a new module called “iisnode” which points to a “.dll”.

Great, we have all the requirements in place.

The very first thing to do is to actually create our Nodejs application.

Creating Nodejs Application

I will create it under “C:\sites\nodejsApp”.

Open Command Prompt, change directory to where you have your app and initialize a NPM project: npm init.

Set the options, the only thing that I modified, althought it is not mandatory, is that the entry point of my application will be “server.js”.



C:\Users\azureuser>cd C:\sites\nodejsApp

C:\sites\nodejsApp>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nodejsapp)
version: (1.0.0)
description: Testing nodejs inside IIS
entry point: (index.js) server.js
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\sites\nodejsApp\package.json:

{
"name": "nodejsapp",
"version": "1.0.0",
"description": "Testing nodejs inside IIS",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

This will create a “package.json” inside your application.

Next step is to create the “server.js” file, which is my entry point. But you could use another name.

You could use Express or other framework, but right now we will only need Nodejs and what already comes with it.

Here, what we are doing the following:

  • Create HTTP server.
  • Send status code 200 and saying we will be sending a response that should be interpreted as “application/json”.
  • Ending our message with the following data: name, version of iisnode, and version of Nodejs.
  • process.env.PORT is mandatory. It is just the way it works. This is an environmental variable.
const http = require('http');

http.createServer((req, res) => {

res.writeHead(200, {'Content-Type': 'application/json'});

res.end(JSON.stringify({

name: "Nodejs IIS!",
iisnodeV : process.env.IISNODE_VERSION,
nodeV : process.version,

}));

}).listen(process.env.PORT);

IIS Section

Creating IIS Site

It is not mandatory, however, I will create a new site called “NodeJSApp”, with its own Application Pool”, and pointing to where we created our Nodejs Application.

This site will be accessible under port 8000.

Handler Mapping

We need to create a handler mapping. Meaning, we need to tell IIS that “server.js” should be handled by a module called “iisnode”.

But before doing this, we need to change “handler mapping” module permissions. As, by default, they can only be read.

So, in order to change it, we need Read/Write permissions.

Open IIS Manger > At Server level > Feature Delegation >Handler Mapping > Read/Write

IIS Manager > Your Site > Handler Mapping Module > Add Module Mapping

Or you can always paste it in the “web.config”. Same thing.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
</system.webServer>
</configuration>

URL Rewrite Module

We need a way to tell IIS that all requests to this website are going to be managed by “server.js”.

URL Rewrite module, can help us with this. We need a rule that sends all requests to “server.js”. You can customize this rule as much as you would like. For example, you could say only requests to “http://localhost/nodejs” are send to “server.js”. However, for this example, I will send all requests to “server.js”.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReqToServerjs">
<match url=".*" />
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Note that this rule was applied at Site level, my site is only accessible through “http://localhost:8000”.

This rule will do the following (examples):

Testing

Finally, we are at the testing stage.

So, a request to http://localhost:8000/var/foo should internally be rewrited as http://localhost:8000/server.js and this should display some data.

If you got an error like “iisnode module is unable to start the node.exe process”, what you can do is to specify the whole path where “node.exe” is.

IIS Manager > Configuration Editor > system.webServer/iisnode > nodeProcessCommandLine > C:\Program Files\nodejs\node.exe

Request to http://localhost:8000/test?age=10 should also be rewriten to http://localhost:8000/server.js.

We are done!

Congratulation!

The final version of our “web.config” would look like this:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="ReqToServerjs">
<match url=".*" />
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
<iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
</system.webServer>
</configuration>

Extra

When creating projects some folders are created as well, folders that should not be publicly accessible.

Request Filtering

We can use Request Filtering Module to denied access to these kinds of folders:

Request Filtering > Hidden Segments

In “web.config”:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="iisnode" />
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>

IISNode Configuration

This will be under “system.webServer/iisnode”

You can configure IISnode through Configuration Editor:

Resources

--

--