Geek With Opinions

Node.js running on Azure.

September 11, 2013

Recently I created a little node.js project for fun. It sole reason for existing is to display Bastard Operator from Hell quotes. I ended up deploying this little project to a free azure website because this little project used edge.js and required C#. Azure websites runs on windows and has .NET installed. Yes even node.js websites run on windows.

Time to jump right into it. I spent entirely too much time getting my little project deployed. Why? Well, the documentation for azure is incomplete. Little did I know, I was missing a key piece of info. To run node.js in azure, one needs a web.config file. If you use one of the templates it will be created for you. If you don’t use a template, you have to created. This is/was not documented.

Why does node.js require a web.config to run in azure? Well node.js in azure runs on IIS. Yeah, that IIS. If I am not mistaken, it is using iisnode. Honestly, this is ok given that azure runs windows and IIS is pretty decent at managing resources. But for the love of sanity, could this be written somewhere please?

How did I figure this out? By luck. I created another website using the template, FTPed into website and noticed a little file with the name web.config. Upon looking at, it is clear as to why it is required.

Here is an example of a web.config, the important piece is line 14. The path should be the name of app start js file.

<!--
     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>

        <handlers>
            <!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
            <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
        </handlers>

        <rewrite>
            <rules>
                <!-- 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>

                <!-- Don't 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 application entry point -->
                <rule name="DynamicContent">
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
                    </conditions>
                    <action type="Rewrite" url="server.js" />
                </rule>
            </rules>
        </rewrite>

        <!-- You can control how Node is hosted within IIS using the following options -->
        <!--<iisnode
          node_env="%node_env%"
          nodeProcessCommandLine="&quot;%programfiles%\nodejs\node.exe&quot;"
          nodeProcessCountPerApplication="1"
          maxConcurrentRequestsPerProcess="1024"
          maxNamedPipeConnectionRetry="3"
          namedPipeConnectionRetryDelay="2000"
          maxNamedPipeConnectionPoolSize="512"
          maxNamedPipePooledConnectionAge="30000"
          asyncCompletionThreadCount="0"
          initialRequestBufferSize="4096"
          maxRequestBufferSize="65536"
          watchedFiles="*.js"
          uncFileChangesPollingInterval="5000"
          gracefulShutdownTimeout="60000"
          loggingEnabled="true"
          logDirectoryNameSuffix="logs"
          debuggingEnabled="true"
          debuggerPortRange="5058-6058"
          debuggerPathSegment="debug"
          maxLogFileSizeInKB="128"
          appendToExistingLog="false"
          logFileFlushInterval="5000"
          devErrorsEnabled="true"
          flushResponse="false"
          enableXFF="false"
          promoteServerVars=""
         />-->

    </system.webServer>
</configuration>

My little project: https://github.com/Oobert/BOFHAA It running in azure: http://bofhaa.azurewebsites.net/#index=359

Update 9/11/2013: I need to clear some things up. As pointed out in the comments there are many ways for azure to auto create a web.config or iisnode.yml file. In my case, I did not use the command line to deployment and ran into a bug with github deployments which would not allow me to publish to azure from github. This bug may be fixed now. In the end, I uploaded my files to azure via FTP, which did not create a file for me. My fun ensued at this point when I couldn’t figure why nothing was happening.

This was not meant as a bash against Azure. I was just putting this out there in case someone else runs into the same issue. Happy Coding!


Tony Gemoll

Written by Tony Gemoll. Shorter opinions found on twitter

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.