Hosting NodeJS application on Windows server
Tags: webdev, backend, windows, node
Published: 2024-06-03 11:50:46

Yes, I know, I know—why would anyone ever like to host NodeJS apps on Windows, right? Well, you obviously haven't had a client who already has a Windows server (probably because of existing .NET applications on it) and wants to host one more app on that server. And that app is written in...(drumroll sound in the background)...NodeJS. Believe me, be thankful it's not WordPress; we'll cover that in another article.

But if this is the first time this scenario has happened to you, Welcome to the world of commercial programming!

This short guide will help you set up Express applications on that Windows bad boy in no time. Let's go through the steps:

**1. Install IISNode on the server**

 

IISNode is an open-source native IIS module written in C++ that allows node.js (node.exe) to be run inside Windows IIS. If you don't know what IIS is, you should read an article about it first.

 

Download and install iisnode via the releases page. Feel free to choose the latest version, and make sure to pick the correct binary package for your architecture (x86/x64).

**2. Tell IIS that you want to use the IISNode module for app.js requests**

 

You can easily do this by adding the following line to your web.config. If you don't have a web.config file, create an empty one and add this line:

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

Your web config should look something like this:

`<configuration>
    <system.webServer>
        <handlers>
            <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
        </handlers>
    </system.webServer>
</configuration>`

**3. You can use the URL Rewrite**

You can use URL Rewrite (IIS native module) to choose which requests get handled by iisnode and which requests will skip iisnode. This is required when setting up a socket.io server inside iisnode. In this case, your web.config would look something like this:


`<rewrite>
  <rules>
    <rule name="app">
      <match url="app/*" />
      <action type="Rewrite" url="app.js" />
    </rule>
  </rules>
</rewrite>`

**4. Set up additional parameters**

This is an introductory article, so I won't discuss theses parameters in depth, but here is a list of parameters and their default values for IISNode:

`<attribute name="node_env" type="string" expanded="true" defaultValue="%node_env%"/>
<attribute name="asyncCompletionThreadCount" type="uint" defaultValue="0"/>
<attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/>
<attribute name="nodeProcessCommandLine" type="string" expanded="true" defaultValue="node.exe"/>
<attribute name="interceptor" type="string" expanded="true"
    defaultValue="&quot;%programfiles%\iisnode\interceptor.js&quot;" />
<attribute name="maxConcurrentRequestsPerProcess" type="uint" allowInfitnite="true" defaultValue="1024"/>
<attribute name="maxNamedPipeConnectionRetry" type="uint" defaultValue="100"/>
<attribute name="namedPipeConnectionRetryDelay" type="uint" defaultValue="250"/>
<attribute name="maxNamedPipeConnectionPoolSize" type="uint" defaultValue="512"/>
<attribute name="maxNamedPipePooledConnectionAge" type="uint" defaultValue="30000"/>
<attribute name="initialRequestBufferSize" type="uint" defaultValue="4096"/>
<attribute name="maxRequestBufferSize" type="uint" defaultValue="65536"/>
<attribute name="uncFileChangesPollingInterval" type="uint" defaultValue="5000"/>
<attribute name="gracefulShutdownTimeout" type="uint" defaultValue="60000"/>
<attribute name="logDirectory" type="string" expanded="true" defaultValue="iisnode"/>
<attribute name="debuggingEnabled" type="bool" defaultValue="true"/>
<attribute name="debuggerExtensionDll" type="string" defaultValue="iisnode-inspector-0.7.3.dll"/>
<attribute name="debugHeaderEnabled" type="bool" defaultValue="false"/>
<attribute name="debuggerVirtualDir" type="string" defaultValue="" />
<attribute name="debuggerPathSegment" type="string" expanded="true" defaultValue="debug"/>
<attribute name="debuggerPortRange" type="string" expanded="true" defaultValue="5058-6058"/>
<attribute name="maxLogFileSizeInKB" type="uint" defaultValue="128"/>
<attribute name="maxTotalLogFileSizeInKB" type="uint" defaultValue="1024"/>
<attribute name="maxLogFiles" type="uint" defaultValue="20"/>
<attribute name="loggingEnabled" type="bool" defaultValue="true"/>
<attribute name="devErrorsEnabled" type="bool" defaultValue="true"/>
<attribute name="flushResponse" type="bool" defaultValue="false"/>
<attribute name="watchedFiles" type="string" expanded="true" defaultValue="*.js;iisnode.yml"/>
<attribute name="enableXFF" type="bool" defaultValue="false"/>
<attribute name="promoteServerVars" type="string" defaultValue=""/>
<attribute name="configOverrides" type="string" expanded="true" defaultValue="iisnode.yml"/>
<attribute name="recycleSignalEnabled" type="bool" defaultValue="false"/>`
 
It is important to set up these parameters properly in different scenarios. For example, you can alter this variable:

`<attribute name="nodeProcessCountPerApplication" type="uint" defaultValue="1"/>`

n order to tell IISNode how many instances of the app it should spawn (similar to PM2 on Linux). It can easily serve as a load balancer!

There are multiple benefits of using IISNode (quoted from the official documentation page):

- **Process management**. The iisnode module takes care of lifetime management of node.exe processes making it simple to improve overall reliability. You don’t have to implement infrastructure to start, stop, and monitor the processes.

- **Side by side with other content types**. The iisnode module integrates with IIS in a way that allows a single web site to contain a variety of content types. For example, a single site can contain a node.js application, static HTML and JavaScript files, PHP applications, and ASP.NET applications. This enables choosing the best tools for the job at hand as well progressive migration of existing applications.
 
- **Scalability on multi-core servers**. Since node.exe is a single threaded process, it only scales to one CPU core. The iisnode module allows creation of multiple node.exe processes per application and load balances the HTTP traffic between them, therefore enabling full utilization of a server’s CPU capacity without requiring additional infrastructure code from an application developer.
 
- **Integrated debugging**. With iisnode integrated debugging you can debug your node.js application deployed to IIS from a browser running on Windows, Mac, or Linux. You get this support out of the box, no extra configuration or installation is necessary. The solution is designed in a way that is shared hosting, firewall, and proxy friendly. The integrated debugging in iisnode uses node-inspector by Danny Coates.
 
- **Auto-update**. The iisnode module ensures that whenever the node.js application is updated (i.e. the script file has changed), the node.exe processes are recycled. Ongoing requests are allowed to gracefully finish execution using the old version of the application, while all new requests are dispatched to the new version of the app.
  
- **Access to logs over HTTP**. The iisnode module provides access the output of the node.exe process (e.g. generated by console.log calls) via HTTP. This facility is key in helping you debug node.js applications deployed to remote servers.
  
- **Minimal changes to node.js application code**. The iisnode module enables hosting of existing HTTP node.js applications with very minimal changes. Typically all that is required is to change the listed address of the HTTP server to one provided by the iisnode module via the process.env.PORT environment variable.
 
- **Integrated management experience**. The iisnode module is fully integrated with IIS configuration system and uses the same tools and mechanism as other IIS components for configuration and maintenance.
 
- **Other IIS benefits**. Port sharing, security, URL rewriting, compression, caching, logging

I hope that you've managed to set everything up. For a further dive, you can read the official Github README.md. If that does not help, feel free to contact us!

Ivan Kockarević