Containerization is the most important aspect to bundle all the dependencies together we called it as container. Container can be an application container, web container or a database container. The advantage of the containerization is to run app anywhere regardless the dependencies because container bundle it with Images. Container engine is used for communication between containers and underlying kernel of Operating System. Docker is the most popular container engine. There are other container engines like rkt, lxc.
To containerize the application with Docker set of instructions to be written. Dockerfile consists all these instructions.
Here we will use sample NodeJs application. The structure of the basic app will be:
app/ — server.js — package.json |
server.js:
const express = require(‘express’); const app = express(); app.get(‘/’, function (req, res) { res.send(‘Hello World!’); }); app.listen(3000, function () { console.log(‘Example app listening on port 3000!’); }); |
Package.json:
{ “name”: “hello-world”, “version”: “1.0.0”, “description”: “Hello world app taken from: https://expressjs.com/en/starter/hello-world.html”, “main”: “server.js”, “scripts”: { “test”: “”, “start”: “” }, “repository”: { “type”: “git”, “url”: “git+https://github.com/borderguru/hello-world.git” }, “author”: “”, “license”: “ISC”, “bugs”: { “url”: “https://github.com/borderguru/hello-world/issues” }, “homepage”: “https://github.com/borderguru/hello-world#readme”, “dependencies”: { “chai”: “^4.1.2”, “express”: “^4.15.3”, “mocha”: “^4.0.1”, “request”: “^2.83.0” } } |
To Dockerize the app, we need to create the Dockerfile:
Dockerfile:
# The official image of the node FROM node:boron # ARG Version to define app version ARG VERSION=1.0.0 # Create app directory inside image WORKDIR /usr/src/app # Set required environment variables ENV NODE_ENV production # Install app dependencies by copying package.json to image COPY package.json . # For [email protected] or later, copy package-lock.json as well # COPY package.json package-lock.json ./ RUN npm install # Bundle app source COPY . . # It will start the app on 3000 port of the container EXPOSE 3000 CMD [ “npm”, “start” ] |
This is well defined dockerfile. Make sure docker should be pre-installed on machine. If it is not installed then, install via official documentation of the docker.
The Dockerfile consists set of commands which includes making work directory where necessary files will be copied. Installing dependencies using npm. Note the base image node:boron is official image from NodeJS and it consists stable npm version. After copying all files and installing dependencies exposing 3000 port of the container and first command will run npm start.
This is sample Dockerfile but it is not limited with just given commands. For more in depth information please check official guide of the Docker for creating Dockerfile.
To create the images from the Dockerfile docker cli is used. Now the app structure is:
app/ — server.js — package.json — Dockerfile |
Run the following command:
$ sudo docker build -t helloworld:1.0 . |
It will build the image and tag it with helloworld:1.0 here 1.0 is the version of image. If nothing is specified then, the latest version will be chosen.
This will download all dependencies to run the app. After successful build, check the images.
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE helloworld 1.0 c812ebca7a95 About a minute ago 678 MB node boron c0cea7b613ca 11 days ago 661 MB |
To run the container docker run command is used. It’s necessary to bind the node port to container port.
$ sudo docker run -it -p 3000:3000 helloworld:1.0 |
Here its binding port 3000 to container port 3000.
Check if app is running:
$ curl localhost:3000 Hello World! |
Tag the image and push to dockerhub:
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE helloworld 1.0 c812ebca7a95 3 hours ago 678 MB node boron c0cea7b613ca 11 days ago 661 MB $ sudo docker tag helloworld:1.0 helloworld:latest $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE helloworld 1.0 c812ebca7a95 3 hours ago 678 MB helloworld latest c812ebca7a95 3 hours ago 678 MB node boron c0cea7b613ca 11 days ago 661 MB |
Tagging image to latest to indicate this will be the most recent version of the image. Dockerhub is the central registry for storing docker images. However, there are many other registries available like JFROG, Quay and Amazon ECR.
Login to dockerhub:
(Notice: If you don’t know dockerhub then please visit https://hub.docker.com and create account)
$ sudo docker login with your Docker ID to push and pull images from Docker Hub. If you don’t have a Docker ID, head over to https://hub.docker.com to create one. Username (kubejack): kubejack Password: Login Succeeded |
$ sudo docker tag helloworld:latest kubejack/helloworld:latest $ sudo docker push kubejack/helloworld:latest The push refers to a repository [docker.io/kubejack/helloworld] 50c9a7dd83b6: Pushed 94df5aea4989: Pushed e7158264ab54: Pushed 54e9e4999177: Pushed 7c966bc7c94e: Mounted from library/node c3031c131aac: Mounted from library/node 7df250eb9e5c: Mounted from library/node e9591a63b7e4: Mounted from library/node d752a0310ee4: Mounted from library/node db64edce4b5b: Mounted from library/node d5d60fc34309: Mounted from library/node c01c63c6823d: Mounted from library/node latest: digest: sha256:952ff7e89547e157630be120126a3e1d8717d45e0df72a1f49901c2bcde74250 size: 2838 |
The image is pushed now and now you can run the app from anywhere with Docker.