summaryrefslogtreecommitdiff
path: root/docs/sources/examples/nodejs_web_app.rst
blob: 68c073da7bed9c3e3db2d03c550058d0d179d18c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
:title: Running a Node.js app on CentOS
:description: Installing and running a Node.js app on CentOS
:keywords: docker, example, package installation, node, centos

.. _nodejs_web_app:

Node.js Web App
===============

.. include:: example_header.inc

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/gasi/docker-node-hello.

Create Node.js app
++++++++++++++++++

First, create a ``package.json`` file that describes your app and its
dependencies:

.. code-block:: json

    {
      "name": "docker-centos-hello",
      "private": true,
      "version": "0.0.1",
      "description": "Node.js Hello World app on CentOS using docker",
      "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:

.. code-block:: javascript

    var express = require('express');

    // Constants
    var PORT = 8080;

    // App
    var app = express();
    app.get('/', function (req, res) {
      res.send('Hello World\n');
    });

    app.listen(PORT)
    console.log('Running on http://localhost:' + PORT);


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 image of your app.

Creating a ``Dockerfile``
+++++++++++++++++++++++++

Create an empty file called ``Dockerfile``:

.. code-block:: bash

    touch Dockerfile

Open the ``Dockerfile`` in your favorite text editor and add the following line
that defines the version of Docker the image requires to build
(this example uses Docker 0.3.4):

.. code-block:: bash

    # DOCKER-VERSION 0.3.4

Next, define the parent image you want to use to build your own image on top of.
Here, we’ll use `CentOS <https://index.docker.io/_/centos/>`_ (tag: ``6.4``)
available on the `Docker index`_:

.. code-block:: bash

    FROM    centos:6.4

Since we’re building a Node.js app, you’ll have to install Node.js as well as
npm on your CentOS image. Node.js is required to run your app and npm to install
your app’s dependencies defined in ``package.json``.
To install the right package for CentOS, we’ll use the instructions from the
`Node.js wiki`_:

.. code-block:: bash

    # Enable EPEL for Node.js
    RUN     rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
    # Install Node.js and npm
    RUN     yum install -y npm

To bundle your app’s source code inside the Docker image, use the ``ADD``
instruction:

.. code-block:: bash

    # Bundle app source
    ADD . /src

Install your app dependencies using the ``npm`` binary:

.. code-block:: bash

    # Install app dependencies
    RUN cd /src; npm install

Your app binds to port ``8080`` so you’ll use the ``EXPOSE`` instruction
to have it mapped by the ``docker`` daemon:

.. code-block:: bash

    EXPOSE  8080

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):

.. code-block:: bash

    CMD ["node", "/src/index.js"]

Your ``Dockerfile`` should now look like this:

.. code-block:: bash


    # DOCKER-VERSION 0.3.4
    FROM    centos:6.4

    # Enable EPEL for Node.js
    RUN     rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
    # Install Node.js and npm
    RUN     yum install -y npm

    # Bundle app source
    ADD . /src
    # Install app dependencies
    RUN cd /src; npm install

    EXPOSE  8080
    CMD ["node", "/src/index.js"]


Building your image
+++++++++++++++++++

Go to the directory that has your ``Dockerfile`` and run the following
command to build a Docker image. The ``-t`` flag let’s you tag your
image so it’s easier to find later using the ``docker images``
command:

.. code-block:: bash

    sudo docker build -t <your username>/centos-node-hello .

Your image will now be listed by Docker:

.. code-block:: bash

    sudo docker images

    > # Example
    > REPOSITORY                 TAG       ID              CREATED
    > centos                     6.4       539c0211cd76    8 weeks ago
    > gasi/centos-node-hello     latest    d64d3505b0d2    2 hours ago


Run the image
+++++++++++++

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:

.. code-block:: bash

    sudo docker run -p 49160:8080 -d <your username>/centos-node-hello

Print the output of your app:

.. code-block:: bash

    # Get container ID
    sudo docker ps

    # Print app output
    sudo docker logs <container id>

    > # Example
    > Running on http://localhost:8080


Test
++++

To test your app, get the the port of your app that Docker mapped:

.. code-block:: bash

    sudo docker ps

    > # Example
    > ID            IMAGE                          COMMAND              ...   PORTS
    > ecce33b30ebf  gasi/centos-node-hello:latest  node /src/index.js         49160->8080

In the example above, Docker mapped the ``8080`` port of the container to
``49160``.

Now you can call your app using ``curl`` (install if needed via:
``sudo apt-get install curl``):

.. code-block:: bash

    curl -i localhost:49160

    > 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
    >
    > Hello World

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
https://github.com/gasi/docker-node-hello.

Continue to :ref:`running_redis_service`.


.. _Node.js wiki: https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#rhelcentosscientific-linux-6
.. _docker index: https://index.docker.io/