Hosting Node.js on Microsoft Azure
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:
- Click "+ New"
- Choose Compute > Website > From Gallery
- Choose Templates > Node JS Empty Site
- 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 assrc/index.js
, be sure to update theweb.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
- IIS
- Node.js (x64)
- Microsoft Visual C++ 2010 Redistributable Package (x64)
- python 2.x
- iisnode (x64)
- URL Rewrite module for IIS - use the Microsoft Platform Installer to install
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.
- Install IIS
- Install Chocolatey
- Run the following:
C:\> choco install python2
C:\> choco install vcredist2010
C:\> choco install nodejs.install
C:\> choco install urlrewrite
- Install iisnode (x64)
Steps to deploy Node.js to iisnode the first time
- Create a new Azure VM, or manage an existing VM
- Install the requirements on the Azure VM
- Add a
web.config
file to your Node.js application - Copy your Node.js application to the VM
- Delete the
node_modules
, if it exists - Run
npm install
to install application dependencies - Add any system environment variables
- 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.
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
- Open up Internet Information Services (IIS) Manager
- Expand the local server
- Right-click Sites, and click Add Website
- Fill out the form, and click OK
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
- Copy your updated Node.js application to the VM
- Delete the
node_modules
, if it exists - Run
npm install
- 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
- Add
winser
as a dependency to your Node.js application - Install the requirements on the Azure VM (see tip on Chocolatey)
- Add any system environment variables
- Copy your Node.js application to the VM
- Delete the
node_modules
, if it exists - Run
npm install
- 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
- Copy your updated Node.js application to the VM
- Delete the
node_modules
, if it exists - Run
npm install
- Stop the service
- Overwrite or merge your old version with the new version
- Start the service