IIS Hosting Nodejs Application
Prerequisites:
- Nodejs & NPM (Nodejs includes NPM)
- 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):
- http://localhost:8000/var/foo => http://localhost:8000/server.js
- http://localhost:8000/test?age=10 => http://localhost:8000/server.js
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
- Download | Node.js (nodejs.org)
- URL Rewrite : The Official Microsoft IIS Site
- GitHub — Azure/iisnode: Hosting node.js applications in IIS on Windows
- Node.js best practices and troubleshooting — Azure App Service | Microsoft Learn
- iisnode/iisnode_schema_x64.xml at master · Azure/iisnode (github.com)
- node.js — host node js on windows server (iis) — Stack Overflow
- node.js — How to host Node JS app on IIS 10 with Windows Server 2019 — Stack Overflow
- Hosting node.js apps in IIS on Windows — (salvatore.netlify.app)
- Hosting node.js applications in IIS on Windows (janczuk.org)