Docker 101: Images & Dockerfiles
I have been working very closely with the DevOps team at the organisation I currently work at. For a guy who comes from a pen-testing background, listening to the word “Docker” day in and day out became frustrating to a point where I decided to just leave security all together for some time and get involved in the DevOps part of things.
For the past few days, I have been binge-watching Docker tutorials, understanding why is it required, what are its benefits and how it saves time and resources. After putting in the work, I have realised that dockers are here to stay for a long time and how beneficial it is for everyone from development to deployment and management.
I published my first article regarding Docker 101: Introduction last week and a lot of people who read it, enjoyed I and found it beneficial. So, you can read it first to have a better idea about Dockers and then go ahead and continue from here on.
In my previous article, I depicted what is Docker, the difference between Docker and the virtual machines that we setup. What are the different commands that are used to manage the dockers and why it is so much more advantageous over virtual machines?
We had our first look at Docker and understanding the basics of it and now we continue from where we dropped off in the previous article i.e. Docker are all amazing and great but how do we actually create it, so here it goes.
Creating images in Docker
To create an image in Docker we need to follow a few steps in a sequential manner. Here are the steps that I will be following where I am trying to create an image for a web server:-
First we need to decide a Linux operating system to build our container upon, for the time being let’s use Ubuntu for example. Once, we have the Ubuntu image ready, then we can update the repositories present in the Ubuntu docker. Install the latest apt packages that would be required for the application to be executed properly. Now that the packages have been upgraded let us install python libraries using pip, during this process we need to remember the exact version of these packages that are required for our application. It is always better to have a developer for the team to help you with these details. Go ahead and copy the source code that needs to be executed in the “/opt” folder. Considering that it is a web server, run the server using the flask command.
That’s how you create an image, carrying out the needed steps to set up your application an have all the dependencies, libraries and toolset required.
I just presented a number of steps that we need to carry out to create a docker image, but the problem is how to run these commands back to back without having made a single mistake, over and over whenever we need to build an image.
That is where Dockerfile comes into play, it helps us create a file where we write these commands in a properly formatted manner. So, that we just have to amend this file according to our needs and everything can be set up easily. There are two important things to note about the Dockerfile:
The commands need to be in order, i.e. we need to put the command to get our OS first and then update the packages, because we can only update the packages if we have an OS hosting those packages. Let’s say if we have five steps in the process of building the docker image and the build process fails at the fourth step, the next time when we build the image the process will start from the fourth step itself and this can save a ton of time when trying out something new and when you want to check how the changes affect the system.
Well, we had a lot of talk about the Dockerfile but we still don’t know what it looks so let me introduce you to a dockerfile.
RUN apt-get update RUN apt-get install python
RUN pip install flask RUN pip install flask-mysql
COPY . /opt/source-code
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
So, this is how a Dockerfile looks like and each of them are commands that needs to be run to create the image.
$ docker build Dockerfile -t <username>/<image-name>
This command is used to build a dockerfile.
$ docker push <username>/<image-name>
This command is used to push the image of the custom app that we have created.
It is better to save the dockerfile in the location where we have the other resources and programs we have written for the docker image, one more thing is that we save the dockerfile with the name “Dockerfile” and we do not append any type of extension to it. It is done such so that we can just enter the following command and everything just works.
$ docker build Dockerfile .
Now, we will discuss the difference between running a command from the CMD and the ENTRYPOINT.
CMD vs ENTRYPOINT
So, before we decide why one is better than the other in certain scenarios and why sometimes we need a combination of both to perfectly set up our image we will see what these commands do and how are they used in the Dockerfile.CMD
CMD is used when we want to execute a certain set of commands directly on the machine. Most of the time these commands are already known to us from the beginning.
Here is an example of how a CMD command looks like in a Dockerfile.
CMD command param e.g. CMD sleep 5
CMD ["command","param"] e.g. CMD ["sleep","5"]
These are the two ways in which we write the CMD command in the dockerfile.ENTRYPOINT
ENTRYPOINT is used when we need to pass parameters during the execution of the image. If there is not a predefined set of instruction that we need to provide or we need to change a certain instruction to our requirement while running the image ENTRYPOINT is more preferred. To give a look of how it works.
$ docker run ubuntu-sleeper 5
Let’s have a look at the docker file for ubuntu-sleeper.
So, now do you understand how entrypoint is used. The value “5” is passed as a parameter in the command while running the docker image and the “sleep” command was already waiting for the parameter to execute properly.
Now, we can easily understand that in scenarios where we already know the exact command that we need to executed using CMD is more useful whereas when we need to change the parameters of the command while running the docker in that situations we use the ENTRYPOINT command.
A combination of both can be used and that can be one of the best options, let’s see how we can do that.
$ docker run ubuntu-sleeper 5
This is the command that we will execute when we want to run our docker image, here “5” is the parameter that is being passed. Now let’s look at the dockerfile.
So let’s breakdown what is exactly happening here. The reason to use both of them is that even if you didn’t pass the parameter in the docker run command there won’t be a problem. This is because even if the docker run command doesn’t have parameter it takes the parameter from the dockerfile but if it does contain a parameter then it overrules the CMD command in the docker file.
This article has shed light on Docker Images and Dockerfile, explaining how to set up a Docker Image, what are the things required to make an Image. It explained why we need them to be in a sequential manner and how to use Dockerfile to create them with ease again and again without having to type the same commands repeatedly.
I have bunch of more articles related to Docker that I will be publishing in this upcoming week. Stay tuned for those.
If you enjoyed it please do clap & let’s collaborate. Get, Set, Hack!
Website : aditya12anand.com | Donate : paypal.me/aditya12anand Telegram : https://t.me/aditya12anand Twitter : twitter.com/aditya12anand LinkedIn : linkedin.com/in/aditya12anand/ E-mail : [email protected]
To present you with this content I had to go through a lot of video content and lab environments.
Docker for Beginners — KodeKloud
Docker for Beginners — Lab Environment
Docker Tutorial for Beginners — Edureka