:title: Node.js Service
:description: dotCloud's Node.js service can host any Node.js application.
:keywords: dotCloud documentation, dotCloud service, Node.js, HTTP server, JavaScript, Node.js workers, signal handlers
Node.js
=======
.. include:: ../dotcloud2note.inc
.. sidebar:: Node.js vs nodejs
`Node.js `_ is the awesome evented I/O platform
to run JavaScript.
nodejs is the name of the dotCloud service offering Node.js capabilities.
The nodejs service can host any Node.js application. The application can
be a HTTP server or just a background worker: the deployment method will
be the same. Background workers will be allocated to a HTTP virtual host as
well, but it won't be used, and so nothing bad will happen.
.. note:: For the impatient...
* create a :ref:`three-lines supervisord.conf file `;
* if you need to install external dependencies, use a standard NPM
:ref:`package.json ` file (but this step is optional);
* if your app should be reachable through HTTP, make sure your code
is setup to listen on port 8080 (don't worry, it will be exposed on
port 80 anyway, but you *need* to listen on port 8080 in your app).
.. include:: service-boilerplate.inc
.. code-block:: yaml
www:
type: nodejs
approot: hellonode
This Build File tells the dotCloud platform that the code for your Node.js
app will be under "hellonode". Our code will have the following structure::
ramen-on-dotcloud/
|_ dotcloud.yml (dotCloud Build File shown above)
|_ hellonode/ (your application root or "approot")
|_ supervisord.conf (mandatory boilerplate file; see next paragraph)
|_ package.json (optional file to specify NPM dependencies)
|_ server.js (your app; can be named differently)
|_ ... (other files: code, static assets...)
.. note::
Your main Node.js program does not have to be called server.js,
but it is "good practice".
.. _nodejs-supervisord:
Assuming that you want to run the code inside the file named "server.js"
located at the root of your application, you need to create the following
"ramen-on-dotcloud/hellonode/supervisord.conf" file:
.. code-block:: ini
[program:node]
command = node server.js
directory = /home/dotcloud/current
.. note::
When you will push your code to dotCloud, it will be groomed by the
builder process, and your approot will be mapped to /home/dotcloud/current.
That's why you need to specify this path.
You can configure many options in the *[program:x]* section (like environment
variables). See the `Supervisor reference
`_
for more information.
.. note::
We called the Supervisor configuration section "program:node", but
"program:anything" will do as well. Just in case you were wondering.
We don't need to specify any extra dependency for our small "Hello, World!"
app. That will be covered later, in `nodejs-packagejson`.
Let's write a simple Node.js app now. It will answer to every request with
"Hello World!" as well as the list of the HTTP headers found in the request.
Paste the following code into "ramen-on-dotcloud/hellonode/server.js":
.. code-block:: javascript
require('http').createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
output = "Hello World!\n";
for (k in request.headers) {
output += k + '=' + request.headers[k] + '\n';
}
response.end(output);
}).listen(8080);
.. note::
The "node" process will run on port 8080 for security reasons
(port 80 requires root), but don't worry: you will be able to access it
through http://something.dotcloud.com/ without specifying the port number.
.. include:: service-push.inc
Node.js Versions
----------------
The node.js service supports three different branches of Node.js (v0.4.x,
v0.6.x, v0.8.x), it will default to node.js ``v0.4.x`` unless you specify
otherwise. The current versions of each node.js branch are listed in the table
below. Pick the branch that works best for you.
+---------+---------+----------+
| branch | version | variable |
+=========+=========+==========+
| v0.4.x* | v0.4.12 | v0.4.x |
+---------+---------+----------+
| v0.6.x | v0.6.20 | v0.6.x |
+---------+---------+----------+
| v0.8.x | v0.8.3 | v0.8.x |
+---------+---------+----------+
\* Node.js v0.4.x is the default
To configure your service to use a version of Node.js other than ``v0.4.x``, you
will set the ``node_version`` config option in your ``dotcloud.yml``
For example, this is what you would have if you wanted to use Node.js version
``v0.6.x``:
.. code-block:: yaml
www:
type: nodejs
approot: hellonode
config:
node_version: v0.6.x
.. include:: /guides/config-change.inc
WebSockets
----------
A lot of people use Node.js for real-time web applications, and want to leverage
on WebSockets for that purpose. WebSockets is fully supported on dotCloud.
See our :doc:`WebSockets guide ` for more information.
Node.js Workers
---------------
.. include:: worker.inc
.. _nodejs-packagejson:
NPM Dependencies (with package.json)
------------------------------------
If your application already ships a package.json file, it will be automatically
used: just after your code is deployed, "npm install" will be run from
your code directory.
If you want to specify your dependencies that way, you can adapt the
following package.json file:
.. code-block:: javascript
{
"name": "helloworld",
"version": "1.0.0",
"dependencies": {
"express": "2.0.0",
"underscore": ""
}
}
See the `NPM documentation `_ to see the full range of
options available in package.json.
.. _nodejs-port8080:
Listen on Port 8080
-------------------
Your main program (it should be "server.js", right?) must listen
on port 8080. If this confuses you: don't worry, it is usually very
easy to fix. Just look for the ".listen(XXXX);" part in your code and
replace XXXX with 8080.
.. note::
Of course, you can ignore this part if your Node.js program does
not need to listen for HTTP requests. That might be the case if
it will only do background processing, crawling, etc.
Troubleshooting
---------------
You can check if your daemon has been started properly with the following
command::
dotcloud run www supervisorctl status
If everything's fine, you should see an output similar to this one::
node RUNNING pid 975, uptime 0:03:20
Supervisor will capture the output (stdout and stderr) of your programs,
and write it into log files. You can check those logs with the ``dotcloud logs``
command::
dotcloud logs www
.. note::
Anything printed to stderr is written right away in the log file.
However, stdout will be buffered. That means that messages might not
show up immediately. With Node you can use the "util" module to write on
stderr: "require('util').debug".
Press Ctrl+C to stop watching the logs.
Signal Handlers
---------------
If your application needs to do some housekeeping when it exits
(which will happen each time you push a new version of the code,
since the old version will be stopped, and the new one will be started),
you can setup a signal handler.
Just include a snippet similar to the following one:
.. code-block:: javascript
process.on('SIGTERM', function () {
console.log('Got SIGTERM exiting...');
// do some cleanup here
process.exit(0);
});
.. note::
The "Got SIGTERM exiting..." message will never show up in the logs, because
Supervisor stops capturing output as soon as you issue *supervisorctl stop*.
But don't worry, the callback is correctly executed.
*Thanks to Daniel Gasienica for his awesome feedback and ideas.*