A former twenty something in technology

All posts in nodejs

nodeIn my previous most I explained how to get started running a node.js application with Azure WebApps. In this post I will note some more advanced features that I would recommend you consider for your project.

  • Routing static files
  • Multiple Instances
  • Slow Initial Render After Deployment (or timeout)
  • Always On & Application Initialization
  • Kudu notifications & Git SHA

Routing Static Files

IIS is handling the requests for your application initially and then proxying requests into node.exe through a named pipe port. Now while node.js is perfectly capable of handling serving up static resources like images, css, html, etc. why burden it.

Using a simple IIS rule in your web.config you can just have IIS serve the file directly by passing node.

<rule name="StaticContent">
<action type="Rewrite" url="client{REQUEST_URI}"/>
</rule>

Multiple Instances

IISNode is capable of spinning up multiple node processes and assigning them each a unique named pipe port that it will round robin serve requests too. Now while node by default is already async and makes good use processing during IO operations. You may still have some CPU intensive sections of your app and node is basically single threaded.

Multiple instances of your application will easily allow it to scale and will allow it to tolerate a few application faults without taking everyone down.

You can set the nodeProcessCountPerApplication value to acheive multiple node.js instances. These settings can be configured in the web.config but I recommend setting them with the Azure WebApps Application Settings section.

Slow Initial Render After Deployment

Unfortunately Azure WebApps disk IO performance is not wonderful. So for a real world application that contains thousands of node_modules it can take some time for it to read the entire hierarchy into memory before it can start serving HTTP requests. In order for your first request to not timeout in these cases you can extend the namedPipeConnectionRetryDelay timeout (in milliseconds) to something longer than it takes for your application to boot. This will ensure that the first request will wait to the actual response being proxied out to node responds.

Always On & Application Initialization

During a deployment all your node processes will shut down and won’t initialize until the next request comes in. Azure WebApps have a feature called Always On which for a Asp.net application will ensure the application pool is kept running and won’t spin down when idle — aka no requests coming in. —

However that is only part of the equation. For IISNode we need to leverage Application Initialization in order to handle a primer request to spin up the node process as well.

Beware of SSL. It’s important to note that Application Initialization is unable to make HTTPS requests so if you redirect all HTTP requests to HTTPS then you will need to configure at least a specific route that is allowed to handle HTTP requests in order for Application Initialization to work.

<applicationInitialization skipManagedModules="true" doAppInitAfterRestart="true">
<-- Any route that is HTTP accessible -->
<add initializationPage="/warmup" />
</applicationInitialization>

Kudu notifications & Git SHA

If you decided to use continuous integration when you push to your repository. Then you probably experienced the mystery if your application deployed successfully or not. Using the Kudu interface you can go to tools > Web hooks. Using a service like Zapier you can configure a service endpoint to receive notifications when deployment is done, successful or failure. Then do what you want with that information. In my case I post it to a slack channel

With or without notifications it can often be useful to know exact SHA your application is running. This information is available from Azure WebApps Kudu debug console under the path D:\home\site\deployments\active 

A simple file read script will do the trick.

var fs = require('fs');

var filePath = 'D:\home\site\deployments\active');
var version_sha;
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
if (!err){
version_sha = data.toString();
}else{
console.error(err);
}
});

Running Node On Azure Web Apps

Categories: Azure, nodejs
Comments: No

nodeIf you don’t want to manage a virtual machine and just want to take advantage of Azure’s salable web app infrastructure for running your node.js application then this post is for you

I’ve broken this guide into a few key areas of pain that I went through getting the configuration right and reliable.

  • Commit your node_modules (*Your choice…but..)
  • Express & IISNode
  • Continuous Integration, SSH & Private Repositories
  • Kudu is Kool
  • Node versions

Commit your node_modules

I’ve tried pretty much every option that involved not committing your node_modules. This is where I’ve landed so let me explain the pros and cons

I’ll get the con out of the way right away. Yes, you’re committing all your dependencies, code you didn’t write, which will increase the size of your repository.

Now on the flip side lets go over the pros:

  1. Deployments are faster. You only have to deploy your repository and you’re done. No concerns with running npm install during a deployment and getting a untested version of a dependency.
  2. No concerns with network timeouts or latency when downloading thousands of additional files.

Just because you didn’t write it doesn’t mean you’re not responsible for it. At the end of the day it’s your application and you need to take ownership of all facets of it.

Express & IISNode

Azure WebApps come pre-installed with IISNode an open source IIS module allowing you to proxy connections from IIS to Node. Enabling this feature can be done by adding a web.config file to the root if your project with a couple lines of configuration.

If you’ve ever done Asp.net development then a web.config is pretty straight forward to you. But for the node.js folks the web.config is basically an xml based instructions for IIS and .net. In this case it’s going to tell IIS what to do with requests and how to route them into node.

Beware of named pipes. It’s important to know that because IIS is handling the requests on port 80 your node app is actually given a named pipe string for the port instead of a number and that is what IIS will proxy requests through.

Hope that gives you a good idea of how to configure Azure WebApps to run node.js and some of the initial brain teaser issues to solve.

<handlers>
<-- Change path to the entry point of your application -->
<add name="iisnode" path="index.js" verb="*" modules="iisnode" />
</handlers>
<-- All of these properties can be overriden at the application level -->
<iisnode node_env="development" loggingEnabled="true" debuggingEnabled="true" logDirectory="..\LogFiles\nodejs" promoteServerVars="HTTPS" enableXFF="true" />

Continuous Integration, SSH & Private Repositories

If you’re using GitHub you may be interested in doing continuous integration.

Using the Azure setup wizard for continuous integration against your repository will generate a SSH key on that repository. This grants this server access to pull from your repository if it’s public or private which is great. It will also add a web hook to kudu to notify the server when a push on your desired branch is done.

We now have continuous integration and deployment complete right? Well maybe…

Re-assigning SSH Keys

A nice touch of Kudu is that it will by default do a git pull --recurse-submodules allowing you to pull any associated sub modules with your project as well. However because the SSH key is only assigned to the primary project you won’t be authorized to pull the sub modules by default.

You can get around this limitation by logging into your GitHub project and removing the SSH key auto generated by Azure. Then through the Kudu web interface path out to the .ssh directory, D:\home\.ssh and grab the public SSH key. Then add this key to your GitHub account instead of to a specific repository.

Kudu is Kool

Kudu is an open source interface for Azure WebApps that handles deployments and management of your application. It’s really awesome actually. But the primary pain comes during the deployment process.

During a deployment Kudu will launch a deploy.cmd batch script that you can alter to do any unique operations for your project before and after deployment.

Two primary issues you will run into

  • npm install – If you didn’t follow my advice about node_modules then Kudu will have to do npm install causes it to make hundreds of requests to install node_modules.
  • Kudu Sync  Is part of the Kudu deployment process. It’s job is to copy new or changed files. However it can easily become out of sync and mistakenly think it has already copied the file or it’s the same and not replace it.

Maybe I’m just lucky at hitting fringe cases immediately but with a real world project Kudu had my files out of sync after a couple deployments. The good news is because the Kudu deployment script is just a batch script we can do anything you can do with batch.

Robocopy

I’ve been a huge fan of robocopy for years and it’s my go to tool of choice when ensure files and folders are in sync.

Replace:

rem call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 100 -f "%DEPLOYMENT_SOURCE%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd"
call :ExecuteRoboCopy robocopy "%DEPLOYMENT_SOURCE%" "%DEPLOYMENT_TARGET%" /MIR /MT /R:100 /NDL /NP /NFL /XD ".git" /log:"D:\home\LogFiles\deployment.log"

Then you will have robocopy in charge of keeping your repository in sync with your wwwroot deployments.

Node Versions

You can configure Azure WebApps to use a specific of node by Application setting WEBSITE_NODE_DEFAULT_VERSION to the version you desire. Not all versions are available. I recommend using the Kudu interface to path to D:\Program Files (x86)\nodejs to get a list of all the available versions.

Check out my next post on some advanced configurations and some additional recommendations.

 

Separation of concerns using Loopback

Categories: nodejs
Comments: No

StrongLoop_logoA single code base application that contains your server side rendering, API (REST or otherwise), business logic, client side application and testing frameworks is nice when your application is small or you’re showing a demo at a conference. However in the real world your application is likely much larger and intricate than that of a demo made in 5 minutes.

Loopback

A little background. Loopback is a node based framework for building websites and applications created and maintained by Strongloop.

The Strongloop team has provided examples as well as a command line application scaffolding utility to get you up and running quickly. While this scaffold-ed application is full featured and great for getting started. You are still left with an application that was created in 5 minutes. It will need a little thought and work to get it into a real world application.

 Separating out the pieces

The key to making this work is identifying what is required in each project in order to operate and function together.

The primary points to focus on are:

  • Node modules
  • boot scripts
  • exporting module singleton objects (loopback & configuration)
  • middleware
  • model locations (specifically when utilizing loopback-component-passport)

Setup

Simply clone the API and SITE projects into their own directory. Then you can run node . in the api and site directories or create a combination script to start up both

var api = require('./api').loopback;
var site = require('./site');

api.start();
site.start();