Docker For Frontend Developers
Tags: javascript, docker, tutorial, beginners
Published: 2019-05-02 11:52:44

---
title: Docker For Frontend Developers
published: true
description: Docker Introduction
tags: #javascript, #docker, #tutorial, #beginners
cover_image: https://thepracticaldev.s3.amazonaws.com/i/9jdnblslm6id1kxeukw1.jpg
---

> This is short and simple guide of docker, useful for frontend developers.

## Why should you use docker?

Long long back when business needed other application DevOps team would go out and buy a server, without knowing performance requirements of the new apps. This would involve lot of guess work and wastage of capital and resources which could be used for other apps.

Enter Virtual machines or VM, it allowed us to run multiple apps on same servers. but there is a drawback. Every VM needed entire OS to run. Every OS needs CPU, RAM etc to run, it needs patching and licensing, which in turn increases cost and resiliency.

Google started using containers model long time ago to address shortcomings of VM model. Basically what container model means that multiple containers on same host uses same host, freeing up CPU, RAM which could be used elsewhere.

> But how does it helps us developers?

It ensures that the working environment is same for all developers and all servers i.e, production, staging and testing

Anyone can setup the project in seconds, no need to mess with config, install libraries, setup dependencies etc.

> In simple terms docker is a platform that enables us to **develop, deploy, and run** applications with containers.

Let’s take a step back, what does container system look like physically and how is it different from VM.

![1.1 Difference between VM and docker](https://thepracticaldev.s3.amazonaws.com/i/h78f2cogxmuo787ys5xy.png)
<figcaption>1.1 Difference between VM and docker.</figcaption>


As you can see host and it’s resources are shared in containers but not in Virtual Machine.

With that out of the way, let’s dive.

## How to use docker?

For that we need to familiarise ourselves with certain terminology.

![1.2 Visualisation of docker images and docker container]
(https://thepracticaldev.s3.amazonaws.com/i/cs6q2qn2m0zvc9s3geg9.png)
<figcaption>1.2 Visualisation of docker images and docker container</figcaption>


**Docker image**: It is an executable file which contains cutdown operating system and all the libraries and configuration needed to run the application. It has multiple layers stacked on top of each other and represented as single object. A docker image is created using _docker file_, we will get to that in a bit.

**Docker Container:** It is a running instance of docker image. there can be many containers running from same docker image.

## Containerise simple Node.js App

We would try to containerise very node.js simple app, and create a image:

### Your Node.js App

Let’s start by creating folder `my-node-app` ,

```
mkdir my-node-app  
cd my-node-app
```
let ‘s create a simple node server in `index.js` and add following code there:

```
//Load express module with `require` directive

var express = require('express')

var app = express()

//Define request response in root URL (/)  
app.get('/', function (req, res) {  
 res.send('Hello World!')  
})

//Launch listening server on port 8081  
app.listen(8081, function () {  
  console.log('app listening on port 8081!')  
})
```

and save this file inside your `my-node-app` folder.

Now we create a `package.json` file and add following code there:

```
 {

    "name": "helloworld",  
    "version": "1.0.0",  
    "description": "Dockerized node.js app",  
    "main": "index.js",  
    "author": "",  
    "license": "ISC",  
    "dependencies": {  
      "express": "^4.16.4"  
    }

 }
```

At this point you don’t need express or npm installed in your host, because remember dockerfile handles setting up all the dependencies, lib and configurations.

### DockerFile

Let’s create dockerfile and save it inside our `my-node-app folder`. This file has no extension and is named `Dockerfile` . Let go ahead and add following code to our dockerfile.

```
    # Dockerfile  
    FROM node:8  
    WORKDIR /app  
    COPY package.json /app  
    RUN npm install  
    COPY . /app  
    EXPOSE 8081  
    CMD node index.js
```

Now what we are doing here:

`FROM node:8 `— pulls node.js docker image from docker hub, which can be found here [https://hub.docker.com/\_/node/](https://medium.com/r/?url=https%3A%2F%2Fhub.docker.com%2F_%2Fnode%2F)

`WORKDIR /app` -this sets working directory for our code in image, it is used by all the subsequent commands such as `COPY` , `RUN` and `CMD`

`COPY package.json /app` -this copies our package.json from host `my-node-app` folder to our image in `/app` folder.

`RUN npm install` — we are running this command inside our image to install dependencies (node\_modules) for our app.

`COPY . /app `— we are telling docker to copy our files from my-node-app folder and paste it to `/app` in docker image.

`EXPOSE 8081` — we are exposing a port on the container using this command. Why this port ? because in our server in index.js is listening on 8081. By default containers created from this image will ignore all the requests made to it.

### Build Docker Image

Show time. Open terminal , go to your folder `my-node-app` and type following command:

```
     # Build a image docker build -t <image-name> <relative-path-to-your-dockerfile>

    docker build -t hello-world .
```

This command creates a `hello-world` image on our host.

`-t` is used to give a name to our image which is **hello-world** here.

`.` is the relative path to docker file, since we are in folder `my-node-app` we used dot to represent path to docker file.

You will see an output on your command line something like this:

```
    Sending build context to Docker daemon  4.096kB  
    Step 1/7 : FROM node:8  
     ---> 4f01e5319662  
    Step 2/7 : WORKDIR /app  
     ---> Using cache  
     ---> 5c173b2c7b76  
    Step 3/7 : COPY package.json /app  
     ---> Using cache  
     ---> ceb27a57f18e  
    Step 4/7 : RUN npm install  
     ---> Using cache  
     ---> c1baaf16812a  
    Step 5/7 : COPY . /app  
     ---> 4a770927e8e8  
    Step 6/7 : EXPOSE 8081  
     ---> Running in 2b3f11daff5e  
    Removing intermediate container 2b3f11daff5e  
     ---> 81a7ce14340a  
    Step 7/7 : CMD node index.js  
     ---> Running in 3791dd7f5149  
    Removing intermediate container 3791dd7f5149  
     ---> c80301fa07b2  
    Successfully built c80301fa07b2  
    Successfully tagged hello-world:latest
```

As you can see it ran the steps in our docker file and output a docker image. When you try it first time it will take a few minutes, but from next time it will start to use the cache and build much faster and output will be like the one shown above. Now, try following command in your terminal to see if your image is there or not :

```
    # Get a list of images on your host 
    docker images
```

it should have a list of images in your host. something like this

```
    REPOSITORY    TAG      IMAGE ID      CREATED         SIZE  
    hello-world   latest   c80301fa07b2  22 minutes ago  896MB
```

### Run Docker Container

With our images created we can spin up a container from this image.

```
    # Default command for this is docker container run <image-name>  
    docker container run -p 4000:8081  hello-world
```

This command is used to create and run a docker container.

`-p 4000:8081`— this is publish flag, it maps host port 4000 to container port 8081 which we opened through expose command in dockerfile. Now all the requests to host port 4000 will be listened by container port 8081.

`hello-world` — this is the name we gave our image earlier when we ran docker-build command.

You will receive some output like this :

```
    app listening on port 8081!
```

If you want to enter your container and mount a bash terminal to it you can run

```
    # Enter the container
    docker exec -ti <container id> /bin/bash
```

In order to check if container is running or not, open another terminal and type

```
    docker ps
```

You should see your running container like this

```
     CONTAINER ID    IMAGE        COMMAND                  CREATED    
    `<container id>`  hello-world  "/bin/sh -c 'node in…"   11 seconds ago

    STATUS              PORTS                    NAMES  
    Up 11 seconds       0.0.0.0:4000->8081/tcp   some-random-name
```

It means our container with id `<container id>` created from hello-world image, is up and running and listening to port 8081.

Now our small Node.js app is completely containerised. You can run [http://localhost:4000/](http://localhost:4000/) on your browser and you should see something like this:

![1.3 Containerised Node.js App](https://cdn-images-1.medium.com/max/1600/1*EvzalzRBmOZatvRui6j9yQ.png)
<figcaption>1.3 Containerised Node.js App</figcaption>

Voilà, you have containerised your first app.