Menu

Hosting Node.js on Microsoft Azure

March 18, 2015

Got a fresh Node.js application to deploy? Awesome! Microsoft Azure has several options for hosting Node.js applications. In this article, we will be looking specifically at deploying to Windows Server websites and virtual machines.

Azure website

An Azure website is an easy and straightforward way to deploy a Node.js application. From the Azure portal:

  1. Click "+ New"
  2. Choose Compute > Website > From Gallery
  3. Choose Templates > Node JS Empty Site
  4. Enter a name for the site

Congratulations, you now have an Azure website configured for Node.js, ready for you to start uploading your files. Azure conveniently provides a URL to test your application, such as myappname.azurewebsites.net.

This option automatically creates web.config and server.js files. You can use FTP to download these files, make changes, and upload your application. Or, better yet, set up automatic deployment with GitHub, Bitbucket, Dropbox, or a number of other solutions.

Note: If the entry point for your Node.js application is not server.js, such as src/index.js, be sure to update the web.config to point to the correct main file.

Azure virtual machine using iisnode

An Azure Windows Server virtual machine (VM) is a good option if you are more comfortable with managing Windows Server, need to host more than one web application on the same VM (e.g. a mix of Node.js and ASP.NET applications), or have deployment requirements not supported by Azure websites. There are also a number of benefits to using iisnode when hosting a Node.js application on Windows Server.

Requirements for Node.js and iisnode

Note: Use the Windows Server Add Roles and Features Wizard to install IIS. C++ and Python are required to build certain Node.js modules (dependencies).

Pro Tip: Chocolatey

For managing applications on Windows machines, Chocolatey is the way to go. It can save you a lot of time setting up virtual machines, or the next time you decide to pave and reinstall your Windows development PC.

Unfortunately, not all the dependencies required for iisnode are available as Chocolately packages. However, you can save some time installing those that are.

C:\> choco install python2
C:\> choco install vcredist2010
C:\> choco install nodejs.install
C:\> choco install urlrewrite

Steps to deploy Node.js to iisnode the first time

  1. Create a new Azure VM, or manage an existing VM
  2. Install the requirements on the Azure VM
  3. Add a web.config file to your Node.js application
  4. Copy your Node.js application to the VM
  5. Delete the node_modules, if it exists
  6. Run npm install to install application dependencies
  7. Add any system environment variables
  8. Add a new web site to IIS

Why do I need to run npm install?

Some Node modules include C code that must be compiled to match the current OS and architecture (x86 or x64). This makes it possible to develop a Node.js application on one OS (i.e. Mac OS X, Linux, or Windows) and deploy to another OS. Although it's possible to create builds for each target OS and architecture, many times the node_modules folder is not included in deployment. Rather, it is built on the target system using npm install.

Environment variables

Some Node.js applications and frameworks require environment variables for proper configuration, such as production environment settings or database connection information. The key to remember here, these environment variables must be added as system variables.

System variables

You're going to need that web.config

You will need to add a web.config file to your Node.js application to configure iisnode. The following is a sample file. Read the in-line comments carefully.

<configuration>
  <system.webServer>
    <handlers>
      <!-- path to application main file -->
      <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
    </handlers>
    <rewrite>
      <rules>
        <!-- Don't interfere with requests for node-inspector debugging -->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="^server.js\/debug[\/]?" />
        </rule>

        <!-- If you have static content, such as HTML, script files, CSS, or images, put them all in one place, such as a folder named public -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}" />
        </rule>

        <!-- All other URLs are mapped to the Node.js application -->
        <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%"
      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=""
      />-->
    <!-- Updates to any of these files will trigger app restart -->
    <iisnode watchedFiles="*.js;node_modules\*;routes\*.js;views\*.jade;views\account\*.jade;iisnode.yml" />
  </system.webServer>
</configuration>

Add the website to IIS

  1. Open up Internet Information Services (IIS) Manager
  2. Expand the local server
  3. Right-click Sites, and click Add Website
  4. Fill out the form, and click OK

Add Website

Note: It is your responsibility to manage DNS records to point your application's domain (web address) to the Public IP address of the Azure VM.

Your Node.js application is now ready to roll!

Redeploying your app to the VM

  1. Copy your updated Node.js application to the VM
  2. Delete the node_modules, if it exists
  3. Run npm install
  4. Overwrite or merge your old version with the new version

Similar to deploying an ASP.NET application, IIS will detect files have changed and restart the application.

Deploy a Node.js application as a service on a Windows VM

This is a good option if you are more comfortable managing Windows Server, need to host one or more Node.js applications on the same VM, and do not need the complexity of installing IIS and iisnode. This is ideal for applications intended to run without a public-facing UI, such as Node.js application that acts upon messages published to a message queue.

Requirements for Node.js applications

There are many options for running Node.js as a service, especially on Linux or Mac OS X. I have found winser to work well on Windows.

Steps to deploy Node.js applications

  1. Add winser as a dependency to your Node.js application
  2. Install the requirements on the Azure VM (see tip on Chocolatey)
  3. Add any system environment variables
  4. Copy your Node.js application to the VM
  5. Delete the node_modules, if it exists
  6. Run npm install
  7. Run npm run-script install-service

Configuring winser

Winser must be installed as a dependency in your Node.js application and configured in package.json.

npm install --save winser

Next, edit package.json and add the following to your scripts, modifying to match your application's start file and name.

  "scripts": {
    "start": "node index.js",
    "install-service": "winser -i -s -a -n myapp-service-name",
    "uninstall-service": "winser -r -x -s -n myapp-service-name"
  },

Note: Make sure start accurately reflects how your application is run.

Work that Service

With winser correctly configured, installing is a breeze. Open a command prompt and enter the following.

C:\> cd \[path to node.js application]
C:\my-awesome-app> npm run-script install-service

If you look at Server Manager > Tools > Services, or use net start, you should see that your application is now running as a service. Like any other Windows service, you can stop and restart the application.

Uninstall the service

Uninstall is just as easy. Our uninstall-service script in package.json is configured to automatically stop and remove the service.

C:\> cd \[path to node.js application]
C:\my-awesome-app> npm run-script uninstall-service

Redeploying your service to the VM

  1. Copy your updated Node.js application to the VM
  2. Delete the node_modules, if it exists
  3. Run npm install
  4. Stop the service
  5. Overwrite or merge your old version with the new version
  6. Start the service

Comments

10 archived comment(s) from this site's previous comment system. These are read-only — join the discussion above.

  1. Faran Iqbal

    David, I need your help.

  2. Faran Iqbal

    I have made a virtual machine with windows server R2 2012 on windows azure, I have configured mongodb and nodejs restful api on the virtual machine, but i don't know how to make my node app public.

  3. David Neal

    By default, all public ports are turned off on Azure virtual machines. You will need to open a public port in the Azure management portal for HTTP traffic. In the Azure management portal, click on "Virtual machines," click on your virtual machine, and then click on the "Endpoints" tab. From there you can add a public port 80 (HTTP) to point to the port your Node.js application is listening on (private port). Node.js can be listening on port 80, or any other port that is available. Hope this helps!

  4. Quantumventura

    Hello David, we are running node.js/mongoDb/ socket.io as a windows app. The app works fine on a local server but once published on azure, the app is unstable. Keep getting http status 500 and substatus 1013 errors. node.exe works fine but it looks like IIS is the culprit. Our app reads twitter realtime streams based on user defined search criteria. I have 2 questions. a) if we go for dedicated VM instead of running it as windows app, do we still need IIS or we can run without it? b) If IIS server is a must, what are the best debugging tools? someone suggested node inspector. thanks so much. Mike

  5. David Neal

    If you run a dedicated VM, you do not have to use IIS to host Node.js. You can use something like winser to manage an instance of your application as if it were a Windows service (start/stop/restart).

  6. Najam Sikander Awan

    can you please tell how to run a basic web app written with koa.js to host with iis and iisnode. for koa.js you need to put --harmony flag with node

  7. David Neal

    I'm not very familiar with koa.js, but my understanding is if you are using any recent version of Node.js (above v0.11.x) you do not need the --harmony flag. If you are running an older version of Node.js, then this closed issue on GitHub might help: https://github.com/tjanczuk...

  8. Najam Sikander Awan

    i finally got it working. by selecting engine in package.json file then iisnode.yml was generated. And yes you were right with latest versions you dont need to supply --harmony flag. my test koajs web app is working now. http://koa83.azurewebsites....

  9. Najam Sikander Awan

    please check my server.js code https://jsfiddle.net/ryvz2r5s/. my web app on azure show node.js version 4.2.3. also when i ftp to site wwwroot folder there is no iiisnode.yml file available

  10. দেবাশীষ

    in azure app service, I cant run node js app. Its pointing the old version. Please help me to install a latest Node.js and a node module like botpress