21 May 2017, 16:45 Technologies Cloud Foundry Bluemix Development

Configuring a Bluemix Cloud Foundry Application To Run Locally

During the course of a typical day, a Bluemix Garage programming pair will deploy code around twenty times. Each of those code pushes will be unit tested in the Build and Deploy pipeline, integration-tested, and then be subjected to a final smoke test before going live. All of this cloud-based testing is marvellous, but it’s not a substitute for pre-push local testing.

Every Cloud Foundry application has a VCAP_SERVICES environment variable automatically created for it, with details of bound platform services and user-provided services. For unit tests we always stub services, but for integration tests and general ‘exploring the application locally,’ it’s convenient to run against the same services as the live application.

This is trivial to do by creating a local .secrets file (and .gitignore-ing it), and sourcing the .secrets file before running. The .secrets file can be assembled manually by reading from the Bluemix console or inspecting the output of cf env, but it’s easiest to generate it automatically. The Garage has a handy script for generating them. Generating it automatically has an extra advantage; some Bluemix services generate a new set of credentials every time they’re bound to an application. Manually maintaining a .secrets file can be hard work if pushes are frequent. In those cases, it’s best to create an extra set of credentials in the Bluemix console, and name them PERMANENT_CREDENTIALS. If this naming convention is used, the script will prefer the permanent credentials to the transient ones.

For example, the complete workflow to run a Node.js application locally would be:

cf login
script/generateSecrets
. .secrets 
npm start

where the first three steps only have to be done once per terminal window.

Using generateSecrets will pick up a Bluemix setting which puts Node.js into production mode, so you may prefer to comment out the line for sharing environment variables, as follows:

//  write(environmentVariables.join(''));