A Node.js Developer's Guide to Bluemix

74
NodeConf EU Workshop James M Snell <[email protected]> <[email protected]> A Node.js Developer's Guide to Bluemix

Transcript of A Node.js Developer's Guide to Bluemix

Page 1: A Node.js Developer's Guide to Bluemix

NodeConf EU Workshop

James M Snell <[email protected]> <[email protected]>

A Node.js Developer's Guide to Bluemix

Page 2: A Node.js Developer's Guide to Bluemix

Getting Started

Page 3: A Node.js Developer's Guide to Bluemix

3

James M Snell

@jasnell on Github and Twitter

IBM Technical Lead for Node.js

TSC Member

Page 4: A Node.js Developer's Guide to Bluemix

4

http://bluemix.net/

Sign up for Free Trial Account:

http://ibm.co/1M05AMX

(go ahead, it only takes a couple minutes)

Page 5: A Node.js Developer's Guide to Bluemix

5

Node.js v0.12.7 or higher

Bluemix supports Node.js v0.12.7 by default(If you want to use Node v4.0.0 locally, go for it.)

Page 6: A Node.js Developer's Guide to Bluemix

6

$ npm install –g bluemix-workshop$ bluemix-workshop

(This is a nodeschool style workshopper that runs with a minimal UI.)

Page 7: A Node.js Developer's Guide to Bluemix

7

Page 8: A Node.js Developer's Guide to Bluemix

What is Bluemix?The Five Minute or Less Introduction

Page 9: A Node.js Developer's Guide to Bluemix

9

Bluemix is IBM's Platform-as-a-Service Offering.

It's built on top of Cloud Foundry.

It also uses Docker and OpenStack (but we're not covering those today)

Page 10: A Node.js Developer's Guide to Bluemix

10

With Bluemix, you write applications and deploy ("push") them to the server.

Bluemix manages the details– Provisioning VMs – Setting up the Containers– Routing,– Load-Balancing,– Scaling,– Configuring Services, etc

Page 11: A Node.js Developer's Guide to Bluemix

11

Page 12: A Node.js Developer's Guide to Bluemix

12

Page 13: A Node.js Developer's Guide to Bluemix

13

Bluemix can run in a Shared or Dedicated Environment

Page 14: A Node.js Developer's Guide to Bluemix

14

Services Services Services Services

Page 15: A Node.js Developer's Guide to Bluemix

15

"Buildpack" – a collection of scripts that prepare code for execution in Bluemix.

…tells Bluemix how to set up the VM, Container and Runtime for your application to run.

For Node.js applications deployed to Bluemix, the default Buildpack is "sdk-for-nodejs"

Page 16: A Node.js Developer's Guide to Bluemix

Install the CLI

Page 17: A Node.js Developer's Guide to Bluemix

17

You will interact with Bluemix using both the browser-based UI and the Cloud Foundry cf command line client.

Visit:

https://github.com/cloudfoundry/cli/releases

Once installed, cf will be added to your PATH. You may need to restart your terminal session to pick up the change.

$ cf -version

Page 18: A Node.js Developer's Guide to Bluemix

Setting the API Endpoint

Page 19: A Node.js Developer's Guide to Bluemix

19

Once the cf command line tool is installed, you have to tell it about the Bluemix endpoint.

First, what region are you in?

US South (`us-south`):

https://api.ng.bluemix.netEurope United Kingdom (`eu-gb`):

https://api.eu-gb.bluemix.net✔

Page 20: A Node.js Developer's Guide to Bluemix

20

Once the cf command line tool is installed, you have to tell it about the Bluemix endpoint.

Second, set the API endpoint and Login

$ cf api https://api.eu-gb.bluemix.net$ cf login

Enter your Bluemix User ID and Password to authenticate

Page 21: A Node.js Developer's Guide to Bluemix

A Simple App

Page 22: A Node.js Developer's Guide to Bluemix

22

$ mkdir helloworld && cd helloworld && npm init

…name: (helloworld)version: (1.0.0)description:entry point: (index.js)test command:git repository:keywords:author:license: (ISC)…Is this ok? (yes)

Remember what you choose here

Page 23: A Node.js Developer's Guide to Bluemix

23

$ vi index.js var http = require('http');

var server = http.createServer(function(req,res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World');});

server.listen(8888, function() { console.log('The server is running');});

Page 24: A Node.js Developer's Guide to Bluemix

24

$ vi package.json { "name": "helloworld", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node index" }, "author": "", "license": "ISC"}

Add this part!

Page 25: A Node.js Developer's Guide to Bluemix

25

$ npm start

> [email protected] start /Users/james/tmp/helloworld> node index

The server is running

Page 26: A Node.js Developer's Guide to Bluemix

Adding Bluemix Support

Page 27: A Node.js Developer's Guide to Bluemix

27

$ vi index.js var http = require('http');var server = http.createServer(function(req,res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World');});server.listen( process.env.VCAP_APP_PORT || 8888, function() { console.log('The server is running'); });

Page 28: A Node.js Developer's Guide to Bluemix

28

$ vi manifest.yml --- applications: - name: {yourappname} mem: 128M instances: 1 path: . host: {yourappname}

Pick something unique for the application name

http://{yourappname}.mybluemix.net

Page 29: A Node.js Developer's Guide to Bluemix

29

$ vi .cfignore node_modules

$ ls –a

.cfignoreindex.jspackage.jsonmanifest.yml

This tells cf not to upload your local node_modules, Bluemix will install them for you.

Page 30: A Node.js Developer's Guide to Bluemix

30

$ cf push

Page 31: A Node.js Developer's Guide to Bluemix

31

http://{yourappname}.mybluemix.net

Page 32: A Node.js Developer's Guide to Bluemix

32

http://snellworkshop.mybluemix.net

Page 33: A Node.js Developer's Guide to Bluemix

Provisioning and Binding Services

Page 34: A Node.js Developer's Guide to Bluemix

34

Services are additional managed capabilities that can be added to an application.

$ cf marketplace

$ cf marketplace –s rediscloud

$ cf create-service rediscloud 30mb myrediscloud

Creates an instance of the rediscloud service within your account.

Page 35: A Node.js Developer's Guide to Bluemix

35

Services are additional managed capabilities that can be added to an application.

$ cf bind-service {yourappname} rediscloud

$ npm install --save redis

Attach the myrediscloud service instance to your application

Add the redis client module to your application.

Page 36: A Node.js Developer's Guide to Bluemix

36

$ vi index.js var http = require('http');var redis = require('redis');var vcap_services = process.env.VCAP_SERVICES;var rediscloud_service = JSON.parse(vcap_services)["rediscloud"][0];var credentials = rediscloud_service.credentials;

var client = redis.createClient( credentials.port, credentials.hostname, {no_ready_check: true});client.auth(credentials.password);client.on('connect', function() { console.log('Connected to Redis');});

var server = http.createServer(function(req,res) { client.get('last-visit', function(err, reply) { res.writeHead(200, {'Content-Type': 'text/plain'}); client.set('last-visit', new Date().toISOString()); res.write('Last Visit: ' + reply + '\n'); res.end('Hello World'); });});server.listen(process.env.VCAP_APP_PORT || 8888, function() { console.log('The server is running');});

Page 37: A Node.js Developer's Guide to Bluemix

37

$ vi index.js var http = require('http');var redis = require('redis');var vcap_services = process.env.VCAP_SERVICES;var rediscloud_service = JSON.parse(vcap_services)["rediscloud"][0];var credentials = rediscloud_service.credentials;

var client = redis.createClient( credentials.port, credentials.hostname, {no_ready_check: true});client.auth(credentials.password);client.on('connect', function() { console.log('Connected to Redis');});

var server = http.createServer(function(req,res) { client.get('last-visit', function(err, reply) { res.writeHead(200, {'Content-Type': 'text/plain'}); client.set('last-visit', new Date().toISOString()); res.write('Last Visit: ' + reply + '\n'); res.end('Hello World'); });});server.listen(process.env.VCAP_APP_PORT || 8888, function() { console.log('The server is running');});

Page 38: A Node.js Developer's Guide to Bluemix

38

$ vi index.js var http = require('http');var redis = require('redis');var vcap_services = process.env.VCAP_SERVICES;var rediscloud_service = JSON.parse(vcap_services)["rediscloud"][0];var credentials = rediscloud_service.credentials;

var client = redis.createClient( credentials.port, credentials.hostname, {no_ready_check: true});client.auth(credentials.password);client.on('connect', function() { console.log('Connected to Redis');});

var server = http.createServer(function(req,res) { client.get('last-visit', function(err, reply) { res.writeHead(200, {'Content-Type': 'text/plain'}); client.set('last-visit', new Date().toISOString()); res.write('Last Visit: ' + reply + '\n'); res.end('Hello World'); });});server.listen(process.env.VCAP_APP_PORT || 8888, function() { console.log('The server is running');});

Page 39: A Node.js Developer's Guide to Bluemix

39

$ vi index.js var http = require('http');var redis = require('redis');var vcap_services = process.env.VCAP_SERVICES;var rediscloud_service = JSON.parse(vcap_services)["rediscloud"][0];var credentials = rediscloud_service.credentials;

var client = redis.createClient( credentials.port, credentials.hostname, {no_ready_check: true});client.auth(credentials.password);client.on('connect', function() { console.log('Connected to Redis');});

var server = http.createServer(function(req,res) { client.get('last-visit', function(err, reply) { res.writeHead(200, {'Content-Type': 'text/plain'}); client.set('last-visit', new Date().toISOString()); res.write('Last Visit: ' + reply + '\n'); res.end('Hello World'); });});server.listen(process.env.VCAP_APP_PORT || 8888, function() { console.log('The server is running');});

Page 40: A Node.js Developer's Guide to Bluemix

40

$ vi index.js var http = require('http');var redis = require('redis');var vcap_services = process.env.VCAP_SERVICES;var rediscloud_service = JSON.parse(vcap_services)["rediscloud"][0];var credentials = rediscloud_service.credentials;

var client = redis.createClient( credentials.port, credentials.hostname, {no_ready_check: true});client.auth(credentials.password);client.on('connect', function() { console.log('Connected to Redis');});

var server = http.createServer(function(req,res) { client.get('last-visit', function(err, reply) { res.writeHead(200, {'Content-Type': 'text/plain'}); client.set('last-visit', new Date().toISOString()); res.write('Last Visit: ' + reply + '\n'); res.end('Hello World'); });});server.listen(process.env.VCAP_APP_PORT || 8888, function() { console.log('The server is running');});

Page 41: A Node.js Developer's Guide to Bluemix

41

$ cf push

Page 42: A Node.js Developer's Guide to Bluemix

The Bluemix Environment

Page 43: A Node.js Developer's Guide to Bluemix

43

Bluemix uses environment variables to configure your application

VCAP_APP_PORT - The TCP Port

VCAP_APP_HOST - The Hostname

VCAP_SERVICES - *JSON* File with Service Details

VCAP_APPLICATION - *JSON* file with Application details

Page 44: A Node.js Developer's Guide to Bluemix

44

Bluemix uses environment variables to configure your application

VCAP_SERVICES:

{ "rediscloud": { "credentials": { ... }, "label": "rediscloud", "name": "myrediscloud", "plan": "30mb", ... }}

Page 45: A Node.js Developer's Guide to Bluemix

45

Bluemix uses environment variables to configure your application

VCAP_APPLICATION:

{ "application_name": "snellworkshop", "application_urls": [ "snellworkshop.mybluemix.net" ], ...}

Page 46: A Node.js Developer's Guide to Bluemix

46

Bluemix uses environment variables to configure your application

$ cf set-env {myappname} MYENVVAR value

$ cf env {myappname}

$ cf unset-env {myappname} MYENVVAR

Page 47: A Node.js Developer's Guide to Bluemix

Enabling Application Management

Page 48: A Node.js Developer's Guide to Bluemix

48

The Application Management Tools are additional utilities for debugging and managing applications

$ cf set-env {yourappname} BLUEMIX_APP_MGMT_ENABLE proxy+devconsole+shell+inspector+trace

$ cf restage {yourappname}

Enables: • a terminal shell for command line

access to your application's container• a node-inspector instance• debug tracing using log4js, bunyan, etc

Page 49: A Node.js Developer's Guide to Bluemix

49

http://{yourappname}.mybluemix.net/bluemix-debug/manage/

Page 50: A Node.js Developer's Guide to Bluemix

50

http://{yourappname}.mybluemix.net/bluemix-debug/manage/

Page 51: A Node.js Developer's Guide to Bluemix

51

http://{yourappname}.mybluemix.net/bluemix-debug/manage/

Page 52: A Node.js Developer's Guide to Bluemix

52

You can enable tracing using log4js or bunyan

$ npm install --save [email protected]

$ vi index.js

...var log4js = require('log4js');log4js.loadAppender('console');var logger = log4js.getLogger('app');logger.setLevel('ERROR');...logger.info('running...');...

Page 53: A Node.js Developer's Guide to Bluemix

53

Set the trace level from within the Bluemix Dashboard…

Page 54: A Node.js Developer's Guide to Bluemix

54

Set the trace level from within the Bluemix Dashboard…

Page 55: A Node.js Developer's Guide to Bluemix

55

Use cf logs to view the trace output

$ cf logs {yourappname}

$ cf logs --recent {yourappname}

Tails the logs to the console

Prints the most recent logs

Page 56: A Node.js Developer's Guide to Bluemix

Using an alternative buildpack(or, how to use newer versions of Node.js)

Page 57: A Node.js Developer's Guide to Bluemix

57

The default Node.js Buildpack uses Node.js v0.12.7, which is good.

But I want to use the new stuff.

The IBM Node.js Buildpack is based on the open source Cloud Foundry Node.js Buildpack. Nearly all Cloud Foundry Buildpacks can work on Bluemix out of the box.

Page 58: A Node.js Developer's Guide to Bluemix

58

The Heroku Node.js Buildpack:

https://github.com/heroku/heroku-buildpack-nodejs.git

Includes support for the latest Node.js/io.js Binaries

Page 59: A Node.js Developer's Guide to Bluemix

59

You specify the alternate buildpack in the manifest.yml

$ vi manifest.yml

--- applications: - name: {yourappname} mem: 128M instances: 1 path: . host: {yourappname} buildpack: https://github.com/heroku/heroku-buildpack-nodejs.git command: node app

Page 60: A Node.js Developer's Guide to Bluemix

60

And tell package.json which version of the Node runtime to use

$ vi package.json

{ "name": "helloworld", "version": "1.0.0", "main": "./app.js", "scripts": { "start": "node app" }, ..., "engines": { "iojs" : "*" }}

Page 61: A Node.js Developer's Guide to Bluemix

61

$ cf push

Page 62: A Node.js Developer's Guide to Bluemix

User-Provided Services

Page 63: A Node.js Developer's Guide to Bluemix

63

Bluemix supports User-Provided Services.

User Provided Services are essentially service configurations you provide. They are kept separate from your application so that they can be shared and managed just like the services provided by Bluemix itself.

User Provided Services provide an excellent way of providing runtime configuration setting to your applications.

Page 64: A Node.js Developer's Guide to Bluemix

64

For instance, suppose we need to configure a secret for our applications:

$ cf cups session-secret -p secret

secret> this is the secretCreating user provided service session-secret in org jasnell / space dev as jasnell...

$ cf bind-service {yourappname} session-secret

$ cf restage

Page 65: A Node.js Developer's Guide to Bluemix

65

User-Provide Service properties are included in the VCAP_SERVICES environment variable, just like any other service.

Page 66: A Node.js Developer's Guide to Bluemix

Using a Custom Domain Name

Page 67: A Node.js Developer's Guide to Bluemix

67

Bluemix supports Custom Domain Names

By default, Bluemix will create a URL for your application automatically.

This usually follows the pattern:

http://{yourappname}.mybluemix.net

But what if you want to use your own domain name?

Page 68: A Node.js Developer's Guide to Bluemix

68

A few command line calls is all you need.

$ cf create-domain myorg example.org

$ cf map-route {yourappname} example.org --n foo

Then create a CNAME DNS record for your sub-domain:

foo.example.org CNAME {yourappname.mybluemix.net}

Once the DNS records propagate, your application will be available at:

http://foo.example.org

Page 69: A Node.js Developer's Guide to Bluemix

69

You can upload your SSL/TLS certificates via the dashboard:

Page 70: A Node.js Developer's Guide to Bluemix

No-downtime deployment

Page 71: A Node.js Developer's Guide to Bluemix

71

Updating an application on Bluemix will cause the application to restart, forcing a small downtime period.

You can avoid it.

$ cf rename {yourappname} {youappname}-old

$ cf push

$ cf delete {yourappname}-old

Page 72: A Node.js Developer's Guide to Bluemix

Resources:

• Bluemix Documentation - https://www.ng.bluemix.net/docs

• developerWorks -http://www.ibm.com/developerworks/cloud/bluemix/

Page 73: A Node.js Developer's Guide to Bluemix

Q&A

Page 74: A Node.js Developer's Guide to Bluemix

Thank you

James M [email protected]@gmail.comtwitter/github @jasnell