Running Simple Node.js Application
Running a Basic Node.js application inside a Container
The example I’m going to discuss assumes you have a Docker installation that works in your system and a basic understanding of how to work with Node.js . If you are aware of how you must work with Docker , it should be evident that Node.js framework need not be installed on your system, rather we would be using the latest
version of the node
image available from Docker. Hence if needed you may download the image beforehand with the command docker pull node
. (The command automatically pulls
the latest version of the node
image from docker.)
-
Proceed to make a directory where all your working application files would reside. Create a
package.json
file in this directory that describes your application as well as the dependencies. Yourpackage.json
file should look something like this:{ "name": "docker_web_app", "version": "1.0.0", "description": "Node.js on Docker", "author": "First Last <first.last@example.com>", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^4.13.3" } }
-
If we need to work with Node.js we usually create a
server
file that defines a web application. In this case we use theExpress.js
framework (version4.13.3
onwards). A basicserver.js
file would look something like this:var express = require('express'); var PORT = 8080; var app = express(); app.get('/', function (req, res) { res.send('Hello world\n'); }); app.listen(PORT); console.log('Running on https://localhost:' + PORT);
-
For those familiar with Docker, you would have come across a
Dockerfile
. ADockerfile
is a text file that contains all the commands required to build a custom image that is tailored for your application.
Create an empty text file named Dockerfile
in the current directory. The method to create one is straightforward in Windows. In Linux, you may want to execute touch Dockerfile
in the directory containing all the files required for your application.
Open the Dockerfile with any text editor and add the following lines:
FROM node:latest
RUN mkdir -p /usr/src/my_first_app
WORKDIR /usr/src/my_first_app
COPY package.json /usr/src/my_first_app/
RUN npm install
COPY . /usr/src/my_first_app
EXPOSE 8080
-
FROM node:latest
instructs the Docker daemon what image we want to build from. In this case we use thelatest
version of the official Docker imagenode
available from the Docker Hub. -
Inside this image we proceed to create a working directory that contains all the required files and we instruct the daemon to set this directory as the desired working directory for our application. For this we add
RUN mkdir -p /usr/src/my_first_app WORKDIR /usr/src/my_first_app
-
We then proceed to install application dependencies by first moving the
package.json
file (which specifies app info including dependencies) to the/usr/src/my_first_app
working directory in the image. We do this byCOPY package.json /usr/src/my_first_app/ RUN npm install
-
We then type
COPY . /usr/src/my_first_app
to add all the application files and source code to the working directory in the image. -
We then use the
EXPOSE
directive to instruct the daemon to make port8080
of the resulting container visible (via a container-to-host mapping) since the application binds to port8080
. -
In the last step, we instruct the daemon to run the command
node server.js
inside the image by executing the basicnpm start
command. We use theCMD
directive for this, which takes the commands as arguments.CMD [ "npm", "start" ]
- We then create a
.dockerignore
file in the same directory as theDockerfile
to prevent our copy of node_modules
and logs used by our Node.js system installation from being copied on to the Docker image. The .dockerignore
file must have the following content:
node_modules
npm-debug.log
-
Build your image
Navigate to the directory that contains the Dockerfile
and run the following command to build the Docker image. The -t
flag lets you tag your image so it’s easier to find later using the docker images command:
$ docker build -t <your username>/node-web-app .
Your image will now be listed by Docker. View images using the below command:
$ docker images
REPOSITORY TAG ID CREATED
node latest 539c0211cd76 10 minutes ago
<your username>/node-web-app latest d64d3505b0d2 1 minute ago
-
Running the image
We can now run the image we just created using the application contents, the node
base image and the Dockerfile
. We now proceed to run our newly created <your username>/node-web-app
image. Providing -d
switch to the docker run
command runs the container in detached mode,so that the container runs in the background. The -p
flag redirects a public port to a private port inside the container. Run the image you previously built using this command:
$ docker run -p 49160:8080 -d <your username>/node-web-app
-
Print the output of your app by running
docker ps
on your terminal. The output should look something like this.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b701693b294 <your username>/node-web-app "npm start" 20 minutes ago Up 48 seconds 0.0.0.0:49160->8080/tcp loving_goldstine
Get application output by entering docker logs <CONTAINER ID>
. In this case it is docker logs 7b701693b294
.
Output: Running on https://localhost:8080
- From the
docker ps
output, the port mapping obtained is0.0.0.0:49160->8080/tcp
. Hence Docker mapped the8080
port inside of the container to the port 49160 on the host machine. In the browser we can now enterlocalhost:49160
.
We can also call our app using curl
:
$ 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, 08 Jan 2017 14:00:12 GMT
Connection: keep-alive
Hello world