UI Development

Containerizing Node Applications using Docker

Docker is a platform where we can build, run, and share applications with containers. These containers are used to deploy applications in an easy and simple way and these are running instances of container images.

Images are layered alternatives to virtual machine disks. Unlike traditional virtual machines, container images give each of its instances shared access to the host OS through a container runtime. This shared access to the host OS is not found in other virtualization methods.

Few fascinating features/advantages of using the docker containers are below:

  • Flexible: It can also be used for highly complex applications.
  • Lightweight: Containers leverage and share the host kernel.
  • Portable: You can build locally, deploy to the cloud, and run anywhere.
  • Loosely coupled: Containers are highly self-sufficient and encapsulated
  • Immutable: Containers are generated from an image. If changes are done to an image then a new image is made. This makes the changes easy to track and roll back the deployment.

 

Few Commands used for building the docker application are:

  1. FROM: It is the first step in the Dockerfile file where the node version is given for the image to build. We can specify any node version we want or node:current-slim will take the current node version – Long Term Support (LTS)
  2. WORKDIR: to specify that all subsequent actions should be taken from the directory which is given in our image filesystem and it should never be the host’s filesystem.
  3. COPY: it is for copying the file from host to the present location in our image. For example, the file package.json is copied from our host to the image location.
  4. RUN: This command takes bash commands as its arguments. For example, the command “npm install” inside our image filesystem, it will read package.json to determine our app’s node dependencies, and install them
  5. EXPOSE: This is to inform Docker that the container is listening on the specified port at runtime.
  6. CMD: It is directive which is for specifying some metadata in our image that describes how to run a container based on this image. For example node, app.js will run our app.js file in the container
  7. COPY: in the rest of our app’s source code from our host to our image filesystem (. .)
  8. ENV: It’s important to explicitly set any environmental variables that our Node application will expect as constants. For example: ENV NODE_ENV production

These are the commands which are useful in building a docker containerized image. Always start with a FROM command, follow it with the above steps to build our private filesystem.

Image: Dockerfile

Make sure the application running inside the Docker container is not being run as root. It’s better to create a new user without root permissions while creating the image so that it doesn’t exist on the host.

 

TAGS: 

Tags help differentiate between different versions of images. It can be used to identify build versions, etc., Anyway, if no tag is explicitly specified, Docker will assign a default tag of the latest after running docker build.

 

Build: 

To Build our image make sure we have source code and .Dockerfile. Now with the following command, we can get our image.

Here, the image name is node-app:1.0

Image: docker build command

docker build –tag node-app:1.0

 

Run:

To run/start our container with the docker image which we have just built, follow the below steps:

Here, container name is node-app-container

docker run -d –name node-app-container -p 1337:1337 node-app:1.0
  • -d will detach the container in the background.
  • -p is for publishing a containers port to the host
  • –name is for assigning a name to the container

 

The above command is for running a single container if we would like to start a group/bunch of containers we can do it in a simple way using docker services.

 

Image: docker-compose file without docker build command

We can also give build command specified the service itself, the build command which is given in service will look into a local directory and builds the image for us, for instance in the below example build is given in towplus-app service.

To run these services, we just need docker-compose up -d command.

Image: docker-compose up command without build in it

 

Image: docker-compose up command with build in it

 

Now, we have three containers here in the above docker-compose file,

  1. towplus-app container, which builds our sails app into the docker image (node-app:1.0).
  1. towplus-app2 container, which builds our sails app into a docker image (node-app:1.0).
  1. mongodb-app container, which is a dependent service for the above service (Sails App relies on Mongo DB) which uses mongo image from docker hub.

Each container would act as a service. In Sails App, we have to give the reference of the other service name so as to consume the functions from it. In this case “mongodb-app”.

Now, the docker container will be running and we can know the list of containers which are running by a command: docker ps (or) docker-compose ps 

MicroServices:

Now, we have three containers running and the ports are 1337, 1338, and 27017. Here, 1337 and 1338 are running with Sails js and both of them are using MongoDB container for Database access.

Now, we can view our application in a browser at http://localhost:1337. (or) http://localhost:1338

For example:

Like this, we can run ‘n’ number of different containers like frontend/UI, Redis, Nginx as a reverse proxy. 

Conclusion:

Now, we have successfully built an image and also containerized our application which also runs successfully in its container. The next step will be to share our images on Docker Hub, so they can be easily downloaded by anyone and run on any destination machine.

About The Author