NodeJS on Cloudfoundry – New Buildpack
Since my last post about monitoring NodeJS applications on CF (CloudFoundry) things have changed, both the NodeJS and CF worlds are fast moving ones. The default Node buildpack is currently a fork of the Heroku one, so most things explained here are relevant to Heroku as well.
You no longer require a special buildpack to deploy an application on CF and have it monitored by StrongLoop. This also applies by to the New Relic and NodeTime (by AppDynamics) solutions as well. For all three solutions you just have to add a dependency in your applications package.json
file and then require it at the beginning of your main JS file. For New Relic and StrongLoop you also have to add a file in the root of your application containing your api key and other config. NodeTime lets you supply this after the require statement, it’s personal taste but I prefer this as it’s one less file in your application root.
require('nodetime').profile({ accountKey: your_account_key });
The new Node buildpack also brings with it some other changes. Previously you had to specify the command:
in the manifest.yml
file or provide a Procfile
to tell CF how the application should be started. NodeJS, or more specifically NPM (Node Package Manager), provides a set of standard lifecycle hooks for a package that can be specified in your package.json
file. Providing a manifest command or the Procfile still work but it’s best practice to use the NPM lifecycle scripts. The hook of interest is the start
script, this shows an example scripts property in a package.json
.
"scripts": { "start": "node server.js --some_arguments", "test": "gulp test" }
The CF NodeJS buildpack will look for a manifest command first and then fall back to the Procfile if no command is given. If the Procfile isn’t present it will check for the NPM start script hook and if it exists create a Procfile for you with web: npm start
. Finally, if there is no start script, the buildpack will look for a server.js
file in the root of the application and if it exists create a Procfile for you specifying web: node server.js
. So it is enough just to call your main application file server.js
for it to run but it’s best practise to be explicit and specify your NPM start script. Another benefit of using the script hooks is that other services can just call npm start
(or any other lifecycle phase) to start your application without having to know the correct command and arguments. Starting with NPM will also add a number of potentially useful environment variable to your application. Remember that manifests and procfiles are specific to PaaSs like CF and Heroku. You can read more about NPM scripts here https://www.npmjs.org/doc/scripts.html.
Finally, I have created a sample NodeJS application that includes everything I have talked about here and will display the applications environment variables to you. It’s ready to run on any V2 instance of CF. https://github.com/cgfrost/cf-sample-app-nodejs. In this sample application the buildpack is actually specified in the manifest but this is only to ensure you are using the latest NodeJS buildpack as some CF providers haven’t updated yet. As long as you application has a package.json
in the root it will be detected and run as a NodeJS application.