Cloud Foundry Now Supports Auto-Reconfiguration for Node.js Applications

August 14, 2012 Maria Shaldibina

featured-cf-genericCloud Foundry has long supported auto-reconfiguration for Spring and Ruby applications. Now we are pleased to add auto-reconfiguration support for Node.js applications as well. Deploying Node.js applications to Cloud Foundry previously required parsing of environmental variables and overwriting server and service connection function calls to use Cloud Foundry specific parameters. This approach was not intuitive to developers who just started to use Cloud Foundry to deploy their applications. They would need to consult the documentation and figure out what port and host they need to connect to. Moreover, if an application uses services, developers would need to configure their applications to use the proper service connection parameters.

Auto-Reconfiguration in Action

Let’s look at the basic Node.js application. We are going to take some sample code from the

Node.js official website homepage and save it to a file called app.js:

var http = require('http');
http.createServer(function (req, res) {res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');

As we can see, this code sets up your server to listen on your local port 1337. What if we now push this application to CloudFoundry.com ‘as-is’?

$ vmc push example-app
Would you like to deploy from the current directory? [Yn]:
Detected a Node.js Application, is this correct? [Yn]:
Application Deployed URL [example-app.cloudfoundry.com]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [64M]:
How many instances? [1]:
Bind existing services to 'example-app'? [yN]:
Create services to bind to 'example-app'? [yN]:
Would you like to save this configuration? [yN]:
Creating Application: OK
Uploading Application:
 Checking for available resources: OK
 Packing application: OK
 Uploading (0K): OK
 Push Status: OK
Staging Application 'example-app': OK
Starting Application 'example-app': OK

$ curl example-app.cloudfoundry.com
Hello World

We can see that the application is up and running. But how is this possible if we didn’t configure it to listen on a Cloud Foundry application-specific port? This is when auto-reconfiguration comes into play. It automatically detects and modifies server and service connection parameters, so that the application can run and connect to Cloud Foundry services without manually specifying configuration values. As a result, an application that is developed and tested locally can work seamlessly on CloudFoundry.com without any code changes. This was only a basic example of auto-reconfiguration in action. Let’s take a look at a more complex application that needs a database service to run. We are going to create our application using the content management system

Calipso. It is based on the Express framework and uses the MongoDB database. First, we pull Calipso source from Github and install its dependencies. As Calipso depends on a native module, bcrypt, we should use Cloud Foundry’s npm support feature that recently became available. Following that blog post on npm support we create npm_shrinkwrap.json and set “ignoreNodeModules” in cloudfoundry.json. That’s it! Our application is ready to be deployed to CloudFoundry.com. As we deploy the application, we will be creating and binding a MongoDB service to the application.

$ vmc push calipso-app --runtime=node06
Would you like to deploy from the current directory? [Yn]:
Detected a Node.js Application, is this correct? [Yn]:
Application Deployed URL [calipso-app.cloudfoundry.com]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [64M]: 128M
How many instances? [1]:
Bind existing services to 'calipso-app'? [yN]:
Create services to bind to 'calipso-app'? [yN]: y
1: mongodb
2: mysql
3: postgresql
4: rabbitmq
5: redis
6: vblob
What kind of service?: 1
Specify the name of the service [mongodb-c88a9]:
Create another? [yN]:
Would you like to save this configuration? [yN]:
Creating Application: OK
Creating Service [mongodb-c88a9]: OK
Binding Service [mongodb-c88a9]: OK
Uploading Application:
 Checking for available resources: OK
 Processing resources: OK
 Packing application: OK
 Uploading (95K): OK
Push Status: OK
Staging Application 'calipso-app': OK
Starting Application 'calipso-app': OK

As you can see from the output, the application was deployed successfully. If we go to its homepage we can see a welcome message from Calipso where we confirm that we are “awesome”!

Now we can follow the installation wizard steps. With auto-reconfiguration it means that we can just use any value, including the default, for the database setup. After the database is set up, we are ready to create a new article on our blog. And we can see that the connection to the data service is functioning, as the new article is published to our blog: To recap, we downloaded the application source, set up its dependencies, and deployed it to CloudFoundry.com using default connection parameters. The result is a working application. Let’s look now at the technical details on how this was accomplished.

Under the Hood

When your application is staged during the deployment process, Cloud Foundry makes two modifications:

  • Add a cf-autoconfig node module to the application
  • Preload the cf-autoconfig module while bootstrapping your application

The cf-autoconfig module uses the Node.js caching mechanism for module loading. Once a module is loaded, it is cached and requiring the same module elsewhere will take advantage of the cached code. The cf-autoconfig module searches for popular modules node.js applications use for connecting to services. It loads them before application code to redefine functions that connect to a service. Each modification replaces the original connection parameters (host, port, credentials, etc.) with equivalent parameters associated with a matching Cloud Foundry service bound to the application. With this arrangement in place, when application code subsequently loads the same module, attempts to connect to a service will yield a connection to an appropriate Cloud Foundry service. For an example, let’s see how it redefines the connect function of the MongoDB node module:

if ("connect" in moduleData) {
  var oldConnect = moduleData.connect;
  var oldConnectProto = moduleData.connect.prototype;
  moduleData.connect = function () {
    var args = Array.prototype.slice.call(arguments);
    args[0] = props.url;
    return oldConnect.apply(this, args);
  };
  moduleData.connect.prototype = oldConnectProto;
}

Other functions are redefined the same way.

Take a look at the cf-autoconfig module’s source code on Github, and feel free to provide feedback or even a pull request.

Supported Modules

The following is the list of supported modules:

According to search.npmjs.org, most Node.js applications and other modules are dependent on the modules listed above. By providing support for these popular modules, any other modules that use them to form the database connection layer will inherit the benefit of auto-reconfiguration.

Limitations

Auto-reconfiguration of services works only under the following conditions:

  • You are only using one service of a given type. For example, only one mysql or one redis service.
  • You are using service node module from the list of supported modules above, or one that is based on a supported node module for service connections.
  • Your application does not use cf-runtime or cf-autoconfig node modules directly.
  • Your application is a typical Node.js application. (For a complex application you may want to consider opting-out of auto-reconfiguration and using the cf-runtime node module instead, which will be described in the next blog post in this series.)

Opting Out of Auto-Reconfiguration

Auto-reconfiguration can be turned off by providing cloudfoundry.json file in application base folder with the option “cfAutoconfig” set as false.

{ “cfAutoconfig” : false }

In addition, as mentioned above, auto-reconfiguration will not work if the application is using the cf-runtime node module.

Summary

Using auto-reconfiguration is a great way to quickly start deploying Node.js applications to Cloud Foundry. As your application grows and demands more precise control over its services you may need to consider using the cf-runtime node module to get easy access to application properties and services. In the next blog post we are going to show you how to use the cf-runtime node module to simplify connections to Cloud Foundry services.

– Maria Shaldibina The Cloud Foundry Team Don’t have a Cloud Foundry account yet? Sign up for free today

About the Author

Biography

Previous
Shop on the Fly with Karmaloop’s New App for iPhone
Shop on the Fly with Karmaloop’s New App for iPhone

Need hot fashions on the fly? We’ve got a solution for you! Karmaloop.com, a Boston-based web retailer, lau...

Next
Get your volunteering hand ready
Get your volunteering hand ready

Helps Nesting separate rails apps What's the best way to do a request test against another rails app in a ...