Setting Up
Before you can start using Cloud Foundry, a target API is required, along with an API client. For this tutorial, we will use http://run. pivotal.io/ as an example. You can sign up for a free account there. However, these instructions are applicable to any other provider.
Download the cf CLI at https://github.com/cloudfoundry/cli/releases and follow the instructions for your operating system at http://docs.cloudfoundry.org/devguide/installcf/install-go-cli.html.
Test your new installation by running the cf CLI. You should see a listing of available commands and options.
Deploying a Node.js app
Now you're ready to deploy your first app. Let's create a Node.js app. Add the following code to a file named server.js:
var http = require(‘http’);
http.createServer(function(request, response) { response.writeHead(200, {“Content-Type”: “text/plain”}); response.end(“Hello from Cloud Foundry!\n”);
}).listen(process.env.VCAP_APP_PORT);
This is nearly identical to the canonical “Hello, World!” application for Node.js, with one exception. The web server is configured to listen on a port defined by an environment variable named VCAP_APP_PORT. VCAP is the code name for the collection of components that implement the core of Cloud Foundry. In order to manage a massive number of apps, VCAP will assign your app a TCP port to listen to, and its load balancer will automatically direct traffic to each of your app’s processes.
Next, create a file named package.json with the following code:
{
“name”: “hello-refcardz”, “version”: “1.0.0”, “main”: “server.js”, “scripts”: {
“start”: “node server.js”
}
}
The package.json file is required in order for the Node.js buildpack to detect your app as a Node.js app and prepare an appropriate environment.
Now that you have your Cloud Foundry account and the cf CLI, you are ready to deploy. To login and deploy, run the following commands.
$ cf api api.run.pivotal.io
$ cf login -u your-email@example.com
$ cf push hello-refcardz
After successfully pushing your app, you should be able to visit its URL and see the text “Hello from Cloud Foundry!”
Here is an abbreviated example of what you should see:
$ cf api api.run.pivotal.io
Setting api endpoint to api.run.pivotal.io... OK
$ cf login -u your-email@example.com
API endpoint: https://api.run.pivotal.io Uploading hello-refcardz... OK
[...snip...]
Starting hello-refcardz... OK
Checking hello-refcardz... OK
$ curl hello-refcardz.cfapps.io
Hello from Cloud Foundry!
Adding a Service
Now that you can deploy an app, let’s add a service to make it more useful. To see the list of available services and their associated plans, run the following command:
$ cf marketplace
Let’s create a Redis service named hello-redis using the free 25mb plan.
$ cf create-service rediscloud 25mb hello-redis
In order for your app to connect to the Redis service, you must bind the service to your app with the following command:
$ cf bind-service hello-refcardz hello-redis
Cloud Foundry will now generate Redis credentials for your app and expose them using the environment variable named VCAP_ SERVICES at runtime. Now, let’s write some code that makes use of Redis. Open server.js in your text editor and change it to the following:
var http = require(‘http’);
var vcap_services = process.env.VCAP_SERVICES;
var rediscloud_service = JSON.parse(vcap_services) [“rediscloud”][0];
var creds = rediscloud_service.credentials;
var redis = require(‘redis’);
var client = redis.createClient(creds.port, creds.hostname, {no_ready_check: true});
client.auth(creds.password);
http.createServer(function(requesto, response) { client.incr(“counter”);
client.get(“counter”, function(err, count) {
response.writeHead(200, {“Content-Type”: “text/ plain”});
response.end(“This page has been viewed “ + count + “ times\n”);
}); }).listen(process.env.VCAP_APP_PORT);
Now visit your app’s URL and enjoy your shiny new hit counter.
Before we can push our new code, we need to tell Cloud Foundry that we want to use the node_redis library to connect. Update the package.json file to include the redis library then push the code.
{
“name”: “hello-refcardz”, “version”: “1.0.0”, “main”: “server.js”, “dependencies”: {
“redis”: “^0.12.1” },
“scripts”: {
“start”: “node server.js”
}
}
$ cf push hello-refcardz
Now visit your app’s URL and enjoy your shiny new hit counter.
Connecting to Your Service Locally
For development and administration, developers may want to connect to their services within Cloud Foundry from their workstations. You can do this using the service’s credentials and the appropriate client for the server. The service’s credentials are available in the service dashboard. The dashboard’s address can be found by running the cf service command:
$ cf service hello-redis
Assuming you created the Redis service in the previous section, and the redis-cli command is available, you can connect to your service like so:
$ redis-cli -h <host> -p <port> -a <password> -n <db name> $ GET counter
“88”
Scaling Up and Out
If your app requires more than the default amount of memory, you can add more using the cf scale command. (Use the cf app command to see how much memory your app is currently consuming.)
Cloud Foundry does not support auto-scaling. Whether you are deploying to a host provider or hosting Cloud Foundry yourself, you can implement auto-scaling by monitoring memory and CPU usage through the REST API, with the cfoundry client library, or by scripting the cf CLI. This usage data can be used to make decisions to add and remove application instances automatically.
Environment Variables
If you need to configure your app and do not want to use the file system, you can use environment variables. This is especially convenient when you have development and production deployments of your app and do not want to maintain separate config files for things like API tokens, Google Analytics codes, and more. Use the env, set-env, and unset-env commands to view, set, and remove environment variables.
Debugging and Monitoring
Let’s make our app crash occasionally by changing our server.js file to the following code:
var express = require(‘express’);
var expressWinston = require(‘express-winston’); var winston = require(‘winston’);
var errorhandler = require(‘errorhandler’);
var app = express();
app.use(expressWinston.logger({ transports: [
new winston.transports.Console({ json: true,
colorize: true, })
] }));
app.use(errorhandler());
app.get(‘/’, function(req, res, next) { if (Math.random() < 0.3) {
return next(new Error(“Your luck has run out!”)); }
res.end(“It’s your lucky day!”); });
app.listen(process.env.VCAP_APP_PORT);
Notice that we’ve also added the express, winston and winston- express, and errorhandler libraries. Let’s add them to our package.json file so it looks like this:
{
“name”: “hello-refcardz”, “version”: “1.0.0”, “main”: “server.js”, “dependencies”: {
“errorhandler”: “^1.3.4”, “express”: “^4.11.2”, “express-winston”: “^0.2.12”, “winston”: “^0.9.0”
}, “scripts”: {
“start”: “node server.js”
}
}
Now push your app with the cf command, and send it enough requests to see both the successful case and the error. Pull the logs with the cf logs command, and you will see requests logged to logs/stdout.log, and errors with full stack traces logged to logs/stderr.log.
While this tutorial only demonstrates error handling for Node.js apps, the operating principles are the same for all frameworks. STDOUT is logged to logs/stdout.log and STDERR is logged to logs/stderr.log. Additional log files can be pulled with cf logs.
For production use, you might also want to integrate with a third-party logging service such as Loggly or Papertrail for log retention and search, New Relic for performance monitoring, Pingdom for uptime monitoring, and PagerDuty to wake you if things go wrong.
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}