Start with Docker Basics

john sunam
Devnetwork
Published in
7 min readMay 18, 2020

Let’s get started with a simple definition of docker related terminologies.

What is docker?

Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow developers to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package.

What is a container?

Containers are nothing else but are a process that is isolated in something called a namespace.

What is Image?

Image is a read-only template that is made up of a collection of files that bundle together all the essentials, such as installations, application code, and dependencies, required to configure a fully operational container environment.

What is Dockerfile?

Dockerfile is nothing else but plain text file where we define instructions to create an image.

Until now we have gone through some of the basics information that we need before we really get started creating an image. If you want to know more in detail you can go through official docker documentation.

Docker Architecture

For installing docker you can go through this link here.

Note: Default name of the docker file is Dockerfile . If you use different names for a dockerfile then we need to pass -f flag with the name of the docker file while executing build command.

Now let us get started with the instruction that we use in Dockerfile. And create the image. For our better understanding of how we can actually dockerize the real app, we will be taking one simple node app, which I have developed just for this example and will be creating a dockerfile inside the app root folder. Here is a link to that repo node_app.

Let us create a file named Dockerfile inside its app root directory.

$ cd node_app && touch Dockerfile

Open the newly created Dockerfile using your preferred editor. For building an image, we are using different instructions in Dockerfile .

Let's go through each instruction one by one that we use to create image in Dockerfile.

FROM:

From instruction tells us from which image we are starting, it could be an operating system, another image, or a docker image. So we can say that when we are building our image we are always taking another image as our base image. In our case, I will be taking the ubuntu image which is already provided by the docker.

Add FROM statement to node_app/Dockerfile

FROM ubuntu:latest

What above command does is it takes ubuntu:latest as its base image. So when we build our image, the docker first searches for its base image within the local machine. If it doesn’t find then it will automatically download it from the docker hub.

Now let's build our docker image

$ docker build -t node_app:v1

In the above command, you can see -t flag with name node_app:v1which means that we are creating an image of the name node_appwith v1 tag.

When you run this above command you will get the error message like below:

Why are we getting this? It is because we haven’t provided the path /context at which our docker file exists. So now we are providing the path in above build statement i.e .

$ docker build -t node_app:v1 .

After running above command you will get the result like below:

Here above you can see that we have successfully built the docker image node_app:v1. You can see that the docker automatically pulled the ubuntu:latest image which we used as a base image for our image.

You can verify if the image has created or not using the command

$ docker images

which will list out all of your docker images.

You can see a list of images we currently have in our system, one is the base image ubuntu:latest and next is the image that we have created node_app:v1.

RUN: This command is used to run any terminal command that we need. We will be using this command in our image to install a node in ubuntu OS. Let's add some RUN command in our Dockerfile.

FROM ubuntu:latestRUN echo "Installing curl...."RUN apt-get updateRUN apt-get -y install curlRUN  echo "Installing nodejs..."RUN apt-get updateRUN curl -sL https://deb.nodesource.com/setup_12.x | bash -RUN apt-get install --yes nodejsRUN apt-get install --yes build-essential

So as I have added numbers of code but don’t get afraid, what we have done is nothing. We just have setup the environment for running our node app just like what we do in our local machine.

As our local machine was pure Ubuntu OS image so we need to add some packages that we need. Go through each RUN command that I have added you will get it easily. Will explain each line of Run command that have added to file:

  1. Echoed string
  2. Updated the system
  3. Installed Curl
  4. Echoed string
  5. Updated the system
  6. Installed node

That's it, easy right !!

What have we used RUN command actually for? Right…

It is just used for running the Linux command.

WORKDIR: Till now we have setup the required environment for running the app. Now we will be using WORKDIR instruction which will help to define where exactly are we running the command. By default, we might be running in the root directory but after we use WORKDIR and specify directory then we will get switched to that specified directory.

COPY: After we have switched to a specific path now we can copy our required app code to that specified directory using the COPY instruction. First, we will be copying the package file and then whole code files.

FROM ubuntu:latestRUN echo "Installing curl...."RUN apt-get updateRUN apt-get -y install curlRUN  echo "Installing nodejs..."RUN apt-get updateRUN curl -sL https://deb.nodesource.com/setup_12.x | bash -RUN apt-get install --yes nodejsRUN apt-get install --yes build-essential
WORKDIR /usr/src/appCOPY package*.json ./ . ./

Now let's build the image changing the version of the image previously we had v1 and now v2 .

$ docker build -t node_app:v3 .

The above newly added COPY line will copy first the package file and then will copy all the remaining files in the present directory.

Now we have copied all our project code inside the working directory now let's add install command to install the npm package.

RUN npm install

ARG: This instruction which allows us to pass input we build an image. It is a similar concept of passing parameters. We will be creating APP_PORT as an ARG variable for which we will be passing value when we build the image.

ARG APP_PORT

ENV: This instruction will help us set the environment variable. We will be using this instruction to define the ENV variable called APP_PORT which we will be using when running the node app.

ENV APP_PORT=$APP_PORT

Here we are assigning ARG variable to ENV variable in this way we can specify the port on which our node app will run.

EXPOSE: Now we will be adding EXPOSE instruction to our docker file which informs Docker that the container listens on the specified network ports at runtime. So in our case, we will use a port that we pass in ARG variable i.e APP_PORT

EXPOSE $APP_PORT

CMD: This is the instruction that allows the container to be alive. This instruction is used to run the service in the container in FOREGROUND mode.

CMD ["node", "app.js"]

Actual command for running node app is

$ node app.js

So we are doing similar using the CMD instruction in docker.

Now let us see how our Dockerfile look when we add this all above commands

FROM ubuntu:latestARG APP_PORTENV APP_PORT=$APP_PORT
RUN echo "Installing curl...."RUN apt-get updateRUN apt-get -y install curlRUN echo "Installing nodejs..."RUN apt-get updateRUN curl -sL https://deb.nodesource.com/setup_12.x | bash -RUN apt-get install --yes nodejsRUN apt-get install --yes build-essentialWORKDIR /usr/src/appCOPY package*.json ./ . ./RUN npm installEXPOSE $APP_PORTCMD ["node", "app.js"]

Now let us build an image with new v4 and pass the argument variable that we have set in Dockerfile APP_PORT .

$ docker build --build-arg APP_PORT=8080 -t node_app:v4 .

After the image is built successfully now we will be finally running a container.

$ docker run -d -it --name node_app_con  -p 3000:8080 node_app:v4

This above code will run the container using the image node_app:v4 . We are using the port 3000of our host machine and port 8080 of the container. And we give name as node_app_con to our container.

Run the above command and you are now ready with the running container. You can verify it using the command

$ docker ps

which will list all the running containers. You can verify it using the name that we have given it node_app_con .

Create one more file in the app root directory in host machine i.e node_app/.dockerignore which consists of a file that we want to ignore when we copy the file from the host machine to the image.

content of node_app/.dockerignore file:

node_modules

After this visit to the URL

http://localhost:3000/

as we have used port 3000 of our local machine. You will get a node app running.

I have tried to explain the very basic implementation of docker. There is a lot more to explore. So my next blog will be focused on more advanced instruction.

Here is link to Docker Basic(part 2)

--

--