Docker tutorial – Build Docker image for Nodejs application and deploy Docker container

Pinterest LinkedIn Tumblr

To create a custom Docker image you will need a Dockerfile. This file describes all the steps that are required to create one image and would usually be contained within the root directory of the source .code repository for your application.

Anatomy of a Dockerfile

A typical Dockerfile might look something like the one shown here, which will create a container for a Node.js-based application:

FROM node:11.11.0

LABEL "maintainer"=""
LABEL "rating"="Five Stars" "class"="First Class"

USER root

ENV AP /data/app
ENV SCPATH /etc/supervisor/conf.d

RUN apt-get -y update

# The daemons
RUN apt-get -y install supervisor
RUN mkdir -p /var/log/supervisor

# Supervisor Configuration
ADD ./supervisord/conf.d/* $SCPATH/

# Application Code
ADD *.js* $AP/


RUN npm install

CMD ["supervisord", "-n"]

We will discover every command in this Dockerfile step by step:

FROM node:11.11.0

Tell the image to inherit from node:11.11.0, which will pull the most recent Node.js version11.11.0 container.

LABEL “maintainer”=””

The LABEL field provides contact information for the Docker file’s author and application, which populates the Author field in all resulting image metadata.

USER root

By default, Docker runs all processes as root within the container, but you can use the USER instruction to change the default owner. In production mode, due to potential security risks, production containers should almost always be run under the context of a non-privileged user.

ENV AP /data/app
ENV SCPATH /etc/supervisor/conf.d

The ENV instruction allows you to set shell variables that can be used during the build process to simplify the Dockerfile.

RUN apt-get -y update

RUN apt-get -y install supervisor
RUN mkdir -p /var/log/supervisor

you’ll use a collection of RUN instructions to start and create the required file structure that you need, and install some required software dependencies.

ADD ./supervisord/conf.d/* $SCPATH/

ADD .js $AP/

The ADD instruction is used to copy files from the local filesystem into your image. Most often this will include your application code and any required support files to image.


RUN npm install

With the WORKDIR instruction, you change the working directory in the image for the remaining build instructions.

CMD [“supervisord”, “-n”]

And finally you end with the CMD instruction, which defines the command that launches the process that you want to run within the container:

Build image

$ git clone
$ docker build -t example/docker-node-hello:latest  .

if successed you will receive the following response

Sending build context to Docker daemon  15.87kB
Step 1/14 : FROM node:11.11.0
11.11.0: Pulling from library/node
22dbe790f715: Pull complete 
0250231711a0: Pull complete 
6fba9447437b: Pull complete 
c2b4d327b352: Pull complete 
270e1baa5299: Pull complete 
08ba2f9dd763: Pull complete 
edf54285ab13: Pull complete 
4d751c169397: Pull complete 
Digest: sha256:065610e9b9567dfecf10f45677f4d372a864a74a67a7b2089f5f513606e28ede
Status: Downloaded newer image for node:11.11.0
 ---> 9ff38e3a6d9d
Step 2/14 : LABEL "maintainer"=""
 ---> Running in f2386b9ee5a7
Removing intermediate container f2386b9ee5a7
 ---> 87d36d539aa3
Step 3/14 : LABEL "rating"="Five Stars" "class"="First Class"
 ---> Running in 472c7282d976
Removing intermediate container 472c7282d976
 ---> 1c14332a71b7
Step 4/14 : USER root
 ---> Running in a6a2a92a80e5
Removing intermediate container a6a2a92a80e5
 ---> de849ea4c1b2
Step 5/14 : ENV AP /data/app
 ---> Running in c5a96dee7f05
Removing intermediate container c5a96dee7f05
 ---> e15760a32a1a
Step 6/14 : ENV SCPATH /etc/supervisor/conf.d
 ---> Running in bf94ae1cbeb9
Removing intermediate container bf94ae1cbeb9
 ---> d9e78389b525
Step 7/14 : RUN apt-get -y update
 ---> Running in 7ede4753e3f9
Get:1 stretch/updates InRelease [53.0 kB]
Ign:2 stretch InRelease
Get:3 stretch-updates InRelease [93.6 kB]
Get:4 stretch/updates/main amd64 Packages [707 kB]
Get:5 stretch Release [118 kB]
Get:6 stretch Release.gpg [2410 B]
Get:7 stretch/main amd64 Packages [7080 kB]
Fetched 8053 kB in 3s (2062 kB/s)
Reading package lists...
Removing intermediate container 7ede4753e3f9
 ---> d1510bd94fa4
Step 8/14 : RUN apt-get -y install supervisor
 ---> Running in a6649ceaa8bb
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  python-meld3 python-pkg-resources
Suggested packages:
  python-setuptools supervisor-doc
The following NEW packages will be installed:
  python-meld3 python-pkg-resources supervisor
0 upgraded, 3 newly installed, 0 to remove and 150 not upgraded.
Need to get 483 kB of archives.
After this operation, 2157 kB of additional disk space will be used.
Get:1 stretch/main amd64 python-pkg-resources all 33.1.1-1 [166 kB]
Get:2 stretch/main amd64 python-meld3 all 1.0.2-2 [37.3 kB]
Get:3 stretch/main amd64 supervisor all 3.3.1-1+deb9u1 [280 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 483 kB in 0s (711 kB/s)
Selecting previously unselected package python-pkg-resources.
(Reading database ... 29978 files and directories currently installed.)
Preparing to unpack .../python-pkg-resources_33.1.1-1_all.deb ...
Unpacking python-pkg-resources (33.1.1-1) ...
Selecting previously unselected package python-meld3.
Preparing to unpack .../python-meld3_1.0.2-2_all.deb ...
Unpacking python-meld3 (1.0.2-2) ...
Selecting previously unselected package supervisor.
Preparing to unpack .../supervisor_3.3.1-1+deb9u1_all.deb ...
Unpacking supervisor (3.3.1-1+deb9u1) ...
Setting up python-meld3 (1.0.2-2) ...
Setting up python-pkg-resources (33.1.1-1) ...
Setting up supervisor (3.3.1-1+deb9u1) ...
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Removing intermediate container a6649ceaa8bb
 ---> 32553d47e5eb
Step 9/14 : RUN mkdir -p /var/log/supervisor
 ---> Running in 764122db10cf
Removing intermediate container 764122db10cf
 ---> 13a5bf2dcb76
Step 10/14 : ADD ./supervisord/conf.d/* $SCPATH/
 ---> 5be2b518fa41
Step 11/14 : ADD *.js* $AP/
 ---> 9bd4479ab781
Step 12/14 : WORKDIR $AP
 ---> Running in fb40ab4cad4b
Removing intermediate container fb40ab4cad4b
 ---> 38dd2278a996
Step 13/14 : RUN npm install
 ---> Running in dcad8bdc7741
added 18 packages from 16 contributors and audited 18 packages in 5.317s
Removing intermediate container dcad8bdc7741
 ---> fae8a6a17ca5
Step 14/14 : CMD ["supervisord", "-n"]
 ---> Running in 382a4e4766a5
Removing intermediate container 382a4e4766a5
 ---> 21f9e9c8d28a
Successfully built 21f9e9c8d28a
Successfully tagged example/docker-node-hello:latest

Run Docker Image

$ docker run -d -p 8080:8080 example/docker-node-hello:latest

The above command will tells Docker to create a running container in the background from the image (-p) with the example/docker-node-hello:latest tag, and then map port 8080 in the container to port 8080 on the Docker host.

If everything goes as expected, when you access localhost:8080 you will see the following response from Nodejs server.

You can also access Nodejs application via container IP. To show IP container you can use the following command:

$ docker ps 
$docker inspect 1df8e230102c

docker ps command will list all running containers on your host machine, to list all containers (exitted and running) you will need to add flag -a to the end of this command (docker ps -a)

list running containers

Then you use docker inspect <container-id> command to find out all infomation include IP of this container. Now you can use the IP address: to access Nodejs application.

If you read the index.js file, you will notice that part of the file refers to the variable $WHO, which the application uses to determine who it is going to say Hello. Let’s review index.js file

var express = require('express');

// Constants
var DEFAULT_PORT = 8080;
var DEFAULT_WHO = "World";
var PORT = process.env.PORT || DEFAULT_PORT;
var WHO = process.env.WHO || DEFAULT_WHO;

// App
var app = express();
app.get('/', function (req, res) {
  res.send('Hello ' + WHO + '. Wish you were here.\n');

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

Now you can then restart the container and adding one argument to the previous docker run command

$ docker stop 1df8e230102c
$ docker run -d -p 8080:8080 -e WHO="Learn Code 24h" example/docker-node-hello:latest

Now refresh the browser and you will receive the following response: Hello Learn Code 24h. Wish you were here.

docker start with enviroment variable

I'm a full stack developer. I have experiences with Java, Android, PHP, Python, C#, Web development...I hope website will help everyone can learn code within 24h and apply it in working easily.

Comments are closed.