Charm: node-app
Summary
Deploy a node.js application
Charm Store
juju deploy cs:precise/node-app-6
Maintainer
Mark Mims
Series
precise
Description
Deploy a user-defined node.js application
Links
Repository   Bugs
lp:~charmers/charms/precise/node-app/trunk
Interfaces
Provides
Requires
Config
app_url string
install_root string
app_name string
app_scm string
polling_schedule string
app_port int
app_branch string
app_node_env string
app_user string
Details
Readme
# juju charm to deploy a user-defined node.js app

This is an example 
[juju](http://juju.ubuntu.com)
charm to deploy a user-defined node app
directly from revision control.

This charm will be maintained with a general set of hooks
for various services that can be used with node apps
(like mongodb).


# Using this charm

First, edit `config.yaml` to add info about your app.

Then deploy some basic services

    juju deploy node-app myapp
    juju deploy mongodb
    juju deploy haproxy

relate them

    juju add-relation mongodb myapp
    juju add-relation myapp haproxy

scale up your app (to 10 nodes for example)

    juju add-unit -n 10 myapp

open it up to the outside world

    juju expose haproxy

Find the haproxy instance's public URL from 

    juju status

(or attach it to an elastic IP via the aws console)
and open it up in a browser.


## What the formula does

During the `install` hook,

- installs `node`/`npm`
- clones your node app from the repo specified in `app_repo`
- runs `npm` if your app contains `package.json`
- configures networking if your app contains `config/config.js`
- waits to be joined to a `mongodb` service

when related to a `mongodb` service, the formula

- configures db access if your app contains `config/config.js`
- starts your node app as a service


## Charm configuration

Configurable aspects of the charm are listed in `config.yaml`
and can be set by either editing the default values directly
in the yaml file or passing a `myapp.yaml` configuration
file during deployment

    juju deploy --config ~/myapp.yaml node-app myapp

Some of these parameters are used directly by the charm,
and some are passed through to the node app using `config/config.js`.

## Application configuration

The formula looks for `config/config.js` in your app which
starts off looking something like this

    module.exports = config = {
      "name" : "mynodeapp"
      ,"listen_port" : 8000
      ,"mongo_host" : "localhost"
      ,"mongo_port" : 27017
    }


and gets modified with contextually correct configuration information during
either deployment (via the `install` hook) or relation to another service 
(`relation-changed` hook).

This config can be used from within
your application using snippets like

    ...
    var config = require('./config/config')
    ...
      new mongo.Server(config.mongo_host, config.mongo_port, {}),
    ...
    server.listen(config.listen_port);
    ...

Alternatively you could use a "Procfile" in root directory like this:

    web: node app.js

and then get the environment variables from the running environment like this:

    app.set('port', process.env.PORT);

The defined environment variables are:

    NAME
    PORT
    NODE_ENV
    MONGO_HOST
    MONGO_PORT
    MONGO_REPLSET

## Network access

This charm does not open any public ports itself.
The intention is to relate it to a proxy service like
`haproxy`, which will in turn open port 80 to the outside world.
This allows for instant horizontal scalability.

If your node app is itself a proxy and you want it directly exposed,
this can easily be done by adding 

    open-port $app_port

to the bottom of the `install` hook, and then once your stack
is started, you expose

    juju expose myapp

it to the outside world.

By default, juju services within the same environment
can talk to each other on any port over
internal network interfaces.


# Making this work with your node.js app

This charm makes some strong assumptions
about the structure of the node application 
(`config/config.js`) that might not apply to your app.
Please treat this formula as a template that 
you can fork and modify to suit your needs.

The biggest difference between how the charm
behaves for different kind of apps is application
startup.  A simple application will want to start
upon install (startup code goes in the `install` hook),
whereas some applications will not want
to start up until a database has be associated
(startup code goes in the `db-relation-joined` hooks).


# Mirrored

lp:charm/node-app 
Changes  
2013/04/15 Marco Ceppi Marius B. Kotsbak 2013-04-04 Update npm repository when new app code is found in cron polling in cas (revno 34)
2013/03/27 Marco Ceppi GS 2013-03-26 Node.JS PPA has included packages nodejs-dev and npm in nodejs package (revno 33)
2013/03/18 Juan L. Negron Merging MP:152205. (revno 32)
2012/09/17 Juan L. Negron Update the README to reflect the charm store and the name "charm". MP:124716 (revno 31)
2012/05/29 Mark Mims maintainer (revno 30)
2012/04/17 Mark Mims get node from the ppa (revno 29)
2012/02/09 Mark Mims oops (revno 28)
2012/02/09 Mark Mims Merge branch 'dangle' (revno 27)
2012/01/28 Mark Mims strong config types (revno 26)