Windows Azure Websites: Node.js

Earlier this week, Brian posted Windows Azure Websites: a PHP Perspective which covers a lot of generally useful information, even for non-PHP developers. In fact, probably 90% of it is generically useful to anyone interested in using the new web sites feature.

But there are some specific things that Node.js developers need to know about the new web sites feature.

Node detection

If you've poked around the portal interface for web sites, you may have noticed that there's a setting to enable PHP, but not one for node. Instead, the web site looks for the presence of an app.js or server.js file in your deployment and will enable node functionality if either of those files are present.

When an app.js or server.js file is detected, a web.config file will be created for the deployment that contains the configuration information required by iisnode. Note that this file isn't added to the remote git repository, so if you do a pull from the web site's git repository you won't get this file. You can use ftp to connect to the server and find it in the wwwroot directory that contains your web site.

You can of course create your own web.config file as part of your deployment, which will be used instead of the auto-generated one.

App settings

In the portal for your website, under the configure section, there's an app settings area where you can enter key/value pairs. These show up as environment variables in your application. For example, if I set a key of 'foo' with a value of 'bar', then I can access process.env.foo to retrieve the value 'bar' in my application.

There's one trick to this that I always seem to forget; you have to click the save icon at the bottom of the portal to actually save the configuration settings.

This is one of those things that's great for setting values that you need to use, but want to keep secure. Like connection strings, usernames & passwords, etc. Another option is to use it for values that you know will change in the future, but that you don't want to do a full redeploy to change.

Server side npm

So what happens if you deploy a project that doesn't include a node_modules folder? Well, if you have a package.json file that lists required modules, Windows Azure will actually run npm on your web site and try to install those modules. You can see this by creating a new express site using the express command, and then deploying that to a web site using git. You will see the expected output from git, but then you'll see output similar to the following:

 remote: New deployment received.
remote: Updating branch 'master'.
remote: Preparing deployment for commit id '3f69628e8c'.
remote: Preparing files for deployment.
remote: Running NPM.
remote: npm http GET https://registry.npmjs.org/jade
remote: npm http GET https://registry.npmjs.org/express/2.5.8
remote: npm http 200 https://registry.npmjs.org/express/2.5.8
remote: npm http GET https://registry.npmjs.org/express/-/express-2.5.8.tgz
remote: npm http 200 https://registry.npmjs.org/express/-/express-2.5.8.tgz
remote: npm http 200 https://registry.npmjs.org/jade
remote: npm http GET https://registry.npmjs.org/jade/-/jade-0.26.1.tgz
remote: npm http 200 https://registry.npmjs.org/jade/-/jade-0.26.1.tgz
remote: npm WARN excluding symbolic link lib\index.js -> jade.js
remote: npm http GET https://registry.npmjs.org/mime/1.2.4
remote: npm http GET https://registry.npmjs.org/qs
remote: npm http GET https://registry.npmjs.org/mkdirp/0.3.0
remote: npm http GET https://registry.npmjs.org/connect
remote: npm http 200 https://registry.npmjs.org/mime/1.2.4
remote: npm http GET https://registry.npmjs.org/commander/0.5.2
remote: npm http GET https://registry.npmjs.org/mime/-/mime-1.2.4.tgz
remote: npm http 200 https://registry.npmjs.org/qs
remote: npm http 200 https://registry.npmjs.org/mkdirp/0.3.0
remote: npm http GET https://registry.npmjs.org/qs/-/qs-0.4.2.tgz
remote: npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz
remote: npm http 200 https://registry.npmjs.org/connect
remote: npm http GET https://registry.npmjs.org/connect/-/connect-1.8.7.tgz
remote: npm http 200 https://registry.npmjs.org/connect/-/connect-1.8.7.tgz
remote: npm http 200 https://registry.npmjs.org/qs/-/qs-0.4.2.tgz
remote: npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz
remote: npm http 200 https://registry.npmjs.org/mime/-/mime-1.2.4.tgz
remote: npm http 200 https://registry.npmjs.org/commander/0.5.2
remote: npm http GET https://registry.npmjs.org/commander/-/commander-0.5.2.tgz
remote: npm http 200 https://registry.npmjs.org/commander/-/commander-0.5.2.tgz
remote: npm http GET https://registry.npmjs.org/formidable
remote: npm http 200 https://registry.npmjs.org/formidable
remote: npm http GET https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz
remote: npm http 200 https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz
remote: jade@0.26.1 ./node_modules/jade
remote: ├── commander@0.5.2
remote: └── mkdirp@0.3.0
remote:
remote: express@2.5.8 ./node_modules/express
remote: ├── mime@1.2.4
remote: ├── qs@0.4.2
remote: ├── mkdirp@0.3.0
remote: └── connect@1.8.7 (formidable@1.0.11)
remote: SetConsoleTitleW: The operation completed successfully.
remote:
remote: Deploying Web.config to enable Node.js activation.
remote: Deployment successful.

One thing to look out for however is modules that rely on node-gyp to compile native bits during install. The web sites environment doesn't have things that node-gyp depends on (like Python) available, so node-gyp will fail. The workaround is to install and build the native module on a Windows system and then deploy the node_modules folder as part of the git deployment. This way, the compiled bits are already there.

WebMatrix

One of the more interesting things for node developers (who use Windows) is the new WebMatrix 2. It now supports creating node applications, including templates for a basic express site and a 'starter site'. The starter site is based on express, but also includes everyauth, socket.io, a nice theme, and chat functionality. It's pretty much a fully functional site for you to customize and build on. There's a tutorial on using WebMatrix with Node that walks you through creating a basic express site.

Command-line tools

Another new feature with this release is the command-line tools, which are implemented in node and should probably work on every platform that can run a recent version of node.js. There's installers available at https://www.windowsazure.com/en-us/develop/nodejs/, which do things like install node if you don't already have it. But if you already have node you can just run npm install azure -g. Once that completes you have access to the azure command.

The azure command provides functionality for working with a bunch of stuff in Azure, but I'm going to focus on the web site related functionality since that's what this article is about. The web site commands all start with 'site', for example azure site create creates a new site, while azure site delete deletes an existing one. You can get a list of the commands by entering azure site, or help with a specific command by using help such as azure help site create. For more information on the command-line tools, see How to use the Windows Azure Command-line tools.

Import subscription information

Before using the azure command to perform actions against Windows Azure, you have to first download and import your site configuration. You can do this by using azure account download command, which will open a browser and prompt you to login to your subscription and download a .publishsettings file. After you have the file, use azure account import [path to the .publishsettings file]. This stores your subscription information in a .azure directory under your user account home directory. This info is pretty sensitive, so you should secure the folder so only you have access to it, and delete the .publishsettings file after you've finished the import.

Work with web sites

One of the neat things you can do with this is to create a web site, initialize git both on the site and in the local directory, and automatically create an 'azure' remote. You can do this by using the --git parameter, like this:

 azure site create mysite --git 

You'll be prompted for a few things, such as the username for your Windows Azure git configuration, and then it will initialize a local repo and setup a remote for the Windows Azure Web Site. One slight catch to all this; you can't use the command-line tools to create your first web site. That currently has to be done using the web portal.

The other web site specific commands are pretty much what you'd expect; list, delete, etc. But there's one more I'd like to call your attention to, the deployments command. You can use this to list out all the deployments that have been performed against a web site, view information for each specific deployment, and even roll back to one of the earlier deployments. For example, if you use azure site deployment list [sitename] you will see a response similar to the following:

 info:   Executing command site deployment list
+ Enumerating deployments
data:   Time                 Commit id   Status   Author        Message
data:   -------------------  ----------  -------  ------------  --------------
data:   2012-06-14 13:02:40  701bf5deb6  Active   Larry Franks  updating view
data:   2012-06-14 13:00:58  297712b7bc  Success  Larry Franks  initial commit
info:   site deployment list command OK

This tells you that there have been two deployments, and the currently active one has a commit id of 701bf5deb6, but that there was a previous commit. If you want to see more information on that commit you can use azure site deployment show 701bf5deb6 [sitename]. You can specify a -d option to show detailed information also. Let's say that the new deployment is somehow busted and you need to switch back to the previous one. To do that, you can use azure site deployment redeploy 297712b7bc [sitename] and enter Y when asked if you're sure about the redeploy. This will process a little bit and return something similar to the following:

 + Redeploying deployment
+ Enumerating deployments
data:   Time                 Commit id   Status   Author        Message
data:   -------------------  ----------  -------  ------------  --------------
data:   2012-06-14 13:02:40  701bf5deb6  Success  Larry Franks  updating view
data:   2012-06-14 13:12:12  297712b7bc  Active   Larry Franks  initial commit
info:   site deployment redeploy command OK

Note that the deployments are still listed in the order of newest to oldest, but that the older deployment, 297712b7bc, is now Active. Now, if you're more of a UI type person, you can do the same thing from the Deployments section of your web site using the new preview portal. That will list off your deployments, and let you select and roll back to a previous one also.

In conclusion

That's just a brief look at some of the Node.js specific things with Windows Azure Web Sites. The Web Sites feature is pretty neat, though still in preview. So expect it to gain functionality as we go along. We know there are things people want that aren't quite there yet (like SSH for Git instead of HTTPS,) and are listening to your feedback on what you'd like to see with Windows Azure in the future. If you have a suggestion or feedback on how we can improve Windows Azure, go to https://www.mygreatwindowsazureidea.com/ and enter it.

Thanks,

Larry