Monday, February 3, 2014

Deploy a minimal Node.js application to IBM Bluemix

IBM Bluemix documentation[1] provides broad coverage of the platform's many features. Instead of trying to address all these features at the same time, this post will take a layered approach starting with an absolute minimum number of features need to run a Hello World application written for Node.js[2] on Bluemix. Minimum here means that taking away any of the parameters from the code will definitely break the deployment to Bluemix. The concluding section of this post will describe how to use Cloud Foundry[3] manifest.yml file feature to reduce the amount of manual effort needed to deploy an application to Bluemix.

Verify your IBM Bluemix account


Make sure that you have a working IBM ID before you start trying out the application and the instructions in this post.  To obtain an IBM ID:

  1. Visit https://www.ibm.com/account/profile/us?page=reg
  2. Complete the 2 step registration form
  3. In case you have questions check out the IBM ID registration FAQ here: https://www.ibm.com/account/profile/us?page=regfaqhelp

To verify that your IBM ID is working, visit IBM Bluemix https://ace.ng.bluemix.net/ and sign in with the IBM ID by using the Login button on the upper right. Note that login to IBM Bluemix may break when using Google Chrome with incognito browsing. While writing this blog post, I found that using Chrome in this mode redirected me to https://idaas.ng.bluemix.net/idaas/public/nullnull
and generated an HTML page with the following error message

Error 404: java.io.FileNotFoundException: SRVE0190E: File not found: /public/nullnull

If you encounter a similar problem you should complete the rest of these instructions with incognito browsing turned off.

Prepare the application source code


If you don't have git[4] installed or don't want to use git, you can manually create a separate directory and then copy and paste the source code for main.js and package.json files described here. Otherwise, the git repository for this post is available via https://github.com/cosipov/minimal-hello-world-node-js

Here is the JavaScript source code for main.js file. It is explained in detail below the snippet. main.js is the entry point into the application and has the instructions for the Node.js runtime to start a web server. Anyone familiar with Node.js will immediately recognize that this code snippet returns a "Hello World" message to any HTTP request sent to the web server running the code. There are two variables in the snippet that might be new to you if you haven't worked with Bluemix or Cloud Foundry in the past. The code on line 1:
var port = (process.env.VCAP_APP_PORT || 8192); 
relies on process.env.VCAP_APP_PORT variable which is automatically initialized by the Bluemix environment to 80,  a default port for HTTP traffic.  Use of the || operator  (logical or) on the same line ensures that if we run the main.js code on a local Node.js runtime (i.e. outside of the Bluemix environment), the port number will default to 8192 since VCAP_APP_PORT would be null. Line 2 uses similar logic to set the hostname of the application.

The following JSON code for package.json file is needed to describe to BlueMix that the application requires a Node.js runtime. Regardless of whether you have cloned the git repository for the application or copied and pasted the source code from the snippets above, at this point you should have a directory containing main.js and package.json files.


Deploy and run the application on Bluemix



Both Bluemix and Cloud Foundry rely on a Go based command line tool (called cf) to script common application management tasks. The getting started[5] section of the Bluemix documentation provides references on how to install cf the Cloud Foundry command line tool[7].  Once cf is installed, you can use it to connect to IBM Bluemix[8] as the deployment platform

and then login to Bluemix[9] using your IBM ID (in line 1)


If the target and login commands completed successful you should be ready to deploy and run the application on Bluemix. Ensure that your working directory contains the application files main.js and package.json before running the cf push operation shown in the following snippet. Note that the -n argument specifies that hello-world-node-js-0123456789 should be used as the subdomain(hostname) for the application, -m tells Bluemix to allocate 128 megabytes of memory to the application, while the -c argument tells the Node.js runtime in Bluemix to run the code in the main.js file.


Once started, the cf tool will show you information about the progress of the deployment. If the deployment processes finishes correctly, you should see the "App started" message and your browser should show the Hello World message when visiting https://hello-world-node-js-0123456789.ng.bluemix.net An example of a push session is shown below. Note that parts with your <Your IBM ID> will be different for your session.

Since multiple Bluemix users may try to deploy an application to the same subdomain you may see the 'host is taken' error message (example below) during the deployment process. To work around this problem, simply change the subdomain to a different, unique value.


Simplify deployment with manifest.yml


A better alternative to having the deployment parameters in the command line is to create a Cloud Foundry manifest.yml file. As shown in following snippet the manifest file contains the values that can be specified during the push process. By convention the file starts with three dashes followed by YAML[11] based markup. A detailed description of the manifest file specification is available from the Cloud Foundry website[3]. The next time you will execute cf push, the cf tool will automatically use the contents of the manifest to deploy the application to Bluemix.


References


[1] https://www.ng.bluemix.net/docs/index.jsp
[2] http://www.nodejs.org
[3] http://docs.cloudfoundry.com
[4] https://help.github.com/articles/set-up-git
[5] https://www.ng.bluemix.net/docs/QuickStart.jsp
[6] http://docs.cloudfoundry.com/docs/common/install_ruby.html
[7] http://www.ng.bluemix.net/docs/BuildingWeb.jsp#install-cf
[8] http://www.ng.bluemix.net/docs/BuildingWeb.jsp#connect-bluemix
[9] http://www.ng.bluemix.net/docs/BuildingWeb.jsp#login-bluemix
[10] http://docs.cloudfoundry.com/docs/using/deploying-apps/manifest.html#attributes
[11] http://www.yaml.org