2015-06-07 23:07:20 -04:00
<!-- [metadata]>
+++
title = "Dockerizing a Node.js web app"
description = "Installing and running a Node.js app with Docker"
keywords = ["docker, example, package installation, node, centos"]
[menu.main]
parent = "smn_applied"
+++
<![end-metadata]-->
2014-04-15 20:53:12 -04:00
2015-04-21 11:50:09 -04:00
# Dockerizing a Node.js web app
2014-04-15 20:53:12 -04:00
2015-10-09 19:50:41 -04:00
> **Note**:
> - **If you don't like sudo** then see [*Giving non-root
> access*](../installation/binaries.md#giving-non-root-access)
2015-08-30 10:54:21 -04:00
2015-10-09 19:50:41 -04:00
The goal of this example is to show you how you can build your own
Docker images from a parent image using a `Dockerfile`
. We will do that by making a simple Node.js hello world web
application running on CentOS. You can get the full source code at[https://github.com/enokd/docker-node-hello/](https://github.com/enokd/docker-node-hello/).
2014-04-15 20:53:12 -04:00
## Create Node.js app
First, create a directory `src` where all the files
would live. Then create a `package.json` file that
describes your app and its dependencies:
{
"name": "docker-centos-hello",
"private": true,
"version": "0.0.1",
2014-07-01 18:07:05 -04:00
"description": "Node.js Hello world app on CentOS using docker",
2014-04-15 20:53:12 -04:00
"author": "Daniel Gasienica < daniel @ gasienica . ch > ",
"dependencies": {
"express": "3.2.4"
}
}
Then, create an `index.js` file that defines a web
app using the [Express.js ](http://expressjs.com/ ) framework:
var express = require('express');
// Constants
var PORT = 8080;
// App
var app = express();
app.get('/', function (req, res) {
2014-07-01 18:07:05 -04:00
res.send('Hello world\n');
2014-04-15 20:53:12 -04:00
});
app.listen(PORT);
console.log('Running on http://localhost:' + PORT);
2014-04-23 16:48:28 -04:00
In the next steps, we'll look at how you can run this app inside a
CentOS container using Docker. First, you'll need to build a Docker
2014-04-15 20:53:12 -04:00
image of your app.
2014-04-23 16:48:28 -04:00
## Creating a Dockerfile
2014-04-15 20:53:12 -04:00
Create an empty file called `Dockerfile` :
touch Dockerfile
Open the `Dockerfile` in your favorite text editor
2014-10-21 01:59:23 -04:00
Define the parent image you want to use to build your own image on
2014-06-01 16:48:04 -04:00
top of. Here, we'll use
2014-07-31 02:54:22 -04:00
[CentOS ](https://registry.hub.docker.com/_/centos/ ) (tag: `centos6` )
2014-06-01 16:48:04 -04:00
available on the [Docker Hub ](https://hub.docker.com/ ):
2014-04-15 20:53:12 -04:00
2014-07-31 02:54:22 -04:00
FROM centos:centos6
2014-04-15 20:53:12 -04:00
2014-04-23 16:48:28 -04:00
Since we're building a Node.js app, you'll have to install Node.js as
2014-04-15 20:53:12 -04:00
well as npm on your CentOS image. Node.js is required to run your app
2015-08-30 10:54:21 -04:00
and npm is required to install your app's dependencies defined in
2014-04-15 20:53:12 -04:00
`package.json` . To install the right package for
2014-04-23 16:48:28 -04:00
CentOS, we'll use the instructions from the [Node.js wiki](
https://github.com/joyent/node/wiki/Installing-Node.js-
via-package-manager#rhelcentosscientific-linux-6):
2014-04-15 20:53:12 -04:00
2015-08-30 10:54:21 -04:00
# Enable Extra Packages for Enterprise Linux (EPEL) for CentOS
RUN yum install -y epel-release
2014-04-15 20:53:12 -04:00
# Install Node.js and npm
2015-08-30 10:54:21 -04:00
RUN yum install -y nodejs npm
2014-04-15 20:53:12 -04:00
2015-11-08 08:11:48 -05:00
Install your app dependencies using the `npm` binary:
# Install app dependencies
COPY package.json /src/package.json
RUN cd /src; npm install
2014-07-09 17:13:26 -04:00
To bundle your app's source code inside the Docker image, use the `COPY`
2014-04-23 16:48:28 -04:00
instruction:
2014-04-15 20:53:12 -04:00
# Bundle app source
2014-07-09 17:13:26 -04:00
COPY . /src
2014-04-15 20:53:12 -04:00
2015-08-30 10:54:21 -04:00
Your app binds to port `8080` so you'll use the `EXPOSE` instruction to have
2014-04-23 16:48:28 -04:00
it mapped by the `docker` daemon:
2014-04-15 20:53:12 -04:00
EXPOSE 8080
2014-04-23 16:48:28 -04:00
Last but not least, define the command to run your app using `CMD` which
defines your runtime, i.e. `node` , and the path to our app, i.e. `src/index.js`
(see the step where we added the source to the container):
2014-04-15 20:53:12 -04:00
CMD ["node", "/src/index.js"]
Your `Dockerfile` should now look like this:
2014-07-31 02:54:22 -04:00
FROM centos:centos6
2014-04-15 20:53:12 -04:00
2015-08-30 10:54:21 -04:00
# Enable Extra Packages for Enterprise Linux (EPEL) for CentOS
RUN yum install -y epel-release
2014-04-15 20:53:12 -04:00
# Install Node.js and npm
2015-08-30 10:54:21 -04:00
RUN yum install -y nodejs npm
2014-04-15 20:53:12 -04:00
# Install app dependencies
2015-11-08 08:11:48 -05:00
COPY package.json /src/package.json
2014-04-15 20:53:12 -04:00
RUN cd /src; npm install
2015-11-08 08:11:48 -05:00
# Bundle app source
COPY . /src
2014-04-15 20:53:12 -04:00
EXPOSE 8080
CMD ["node", "/src/index.js"]
## Building your image
2014-04-23 16:48:28 -04:00
Go to the directory that has your `Dockerfile` and run the following command
2014-07-21 04:34:54 -04:00
to build a Docker image. The `-t` flag lets you tag your image so it's easier
2014-04-23 16:48:28 -04:00
to find later using the `docker images` command:
2014-04-15 20:53:12 -04:00
2015-03-26 14:12:37 -04:00
$ docker build -t < your username > /centos-node-hello .
2014-04-15 20:53:12 -04:00
Your image will now be listed by Docker:
2015-03-26 14:12:37 -04:00
$ docker images
2014-04-15 20:53:12 -04:00
2014-05-01 10:13:34 -04:00
# Example
2014-07-31 02:54:22 -04:00
REPOSITORY TAG ID CREATED
centos centos6 539c0211cd76 8 weeks ago
< your username > /centos-node-hello latest d64d3505b0d2 2 hours ago
2014-04-15 20:53:12 -04:00
## Run the image
2014-04-23 16:48:28 -04:00
Running your image with `-d` runs the container in detached mode, leaving the
container running in the background. The `-p` flag redirects a public port to
a private port in the container. Run the image you previously built:
2014-04-15 20:53:12 -04:00
2015-03-26 14:12:37 -04:00
$ docker run -p 49160:8080 -d < your username > /centos-node-hello
2014-04-15 20:53:12 -04:00
Print the output of your app:
# Get container ID
2015-03-26 14:12:37 -04:00
$ docker ps
2014-04-15 20:53:12 -04:00
# Print app output
2015-03-26 14:12:37 -04:00
$ docker logs < container id >
2014-04-15 20:53:12 -04:00
2014-05-01 10:13:34 -04:00
# Example
Running on http://localhost:8080
2014-04-15 20:53:12 -04:00
## Test
2015-02-14 11:41:57 -05:00
To test your app, get the port of your app that Docker mapped:
2014-04-15 20:53:12 -04:00
2015-03-26 14:12:37 -04:00
$ docker ps
2014-04-15 20:53:12 -04:00
2014-05-01 10:13:34 -04:00
# Example
2014-06-26 22:39:58 -04:00
ID IMAGE COMMAND ... PORTS
ecce33b30ebf < your username > /centos-node-hello:latest node /src/index.js 49160->8080
2014-04-15 20:53:12 -04:00
2014-04-23 16:48:28 -04:00
In the example above, Docker mapped the `8080` port of the container to `49160` .
2014-04-15 20:53:12 -04:00
2014-04-23 16:48:28 -04:00
Now you can call your app using `curl` (install if needed via:
`sudo apt-get install curl` ):
2014-04-15 20:53:12 -04:00
2014-05-01 10:13:34 -04:00
$ curl -i localhost:49160
2014-04-15 20:53:12 -04:00
2014-05-01 10:13:34 -04:00
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
Date: Sun, 02 Jun 2013 03:53:22 GMT
Connection: keep-alive
2014-05-21 17:05:19 -04:00
2014-07-01 18:07:05 -04:00
Hello world
2014-04-15 20:53:12 -04:00
2015-07-17 16:05:45 -04:00
If you use Docker Machine on OS X, the port is actually mapped to the Docker
host VM, and you should use the following command:
2015-01-19 03:15:27 -05:00
2015-07-17 16:05:45 -04:00
$ curl $(docker-machine ip VM_NAME):49160
2015-01-19 03:15:27 -05:00
2014-04-15 20:53:12 -04:00
We hope this tutorial helped you get up and running with Node.js and
CentOS on Docker. You can get the full source code at
2014-08-30 03:02:47 -04:00
[https://github.com/enokd/docker-node-hello/ ](https://github.com/enokd/docker-node-hello/ ).