Docker

How Dockerfile Works?

You can deploy only a single container with the help of the docker image. However, if you need to deploy several containers (each for different tasks) from the same image then what happens? You can resolve this with the help of the dockerfile.

Dockerfile is a simple text file that contains all the commands user could call on the command line to assemble or build an image. With the help of docker build, you can easily automate build that runs multiple commands defines in the dockerfile in succession.

For example, you want to download the docker image from the docker hub for your specific development needs. Then, you want to update the image, install some packages for your development process. In this case, you can create a dockerfile, include all parameters for your specific needs, and build your custom image. After creating a dockerfile, you can use it over and over to build the same image without manually installing all required packages for your development process.

Dockerfile Basic

Before working with dockerfile if is important to know how to make a dockerfile. Dockerfile includes specific keywords that can be used to build a specific image. A brief explanation of all keywords used in a dockerfile are listed below:

  • FROM: It is used to define the base image, on which we will be building.
  • ADD: It is used to add files to the container being built. In simple terms, RUN is used to run commands and commits the result
  • RUN: It is used to add layers to the base image, by installing components.
  • CMD: It is used to run commands at the start of the container. These commands run only when there is no argument specified while running the container.
  • ENTRYPOINT: It is used to run commands during the container initialization process. You must use an ENTRYPOINT in your dockefile if you want to start a container automatically after building an image.
  • ENV: It is used to define environment variables in the container run-time.
  • EXPOSE: It is used to specify the listening port to enable networking at run time.
  • MAINTAINER: It is used to specify the name and email id of the image creator.
  • USER: It is used to specify the username used to run the container.
  • VOLUME: It is used to allow access from the container to the directory on the Docker host.
  • WORKDIR: It is used to specify the path of the command to be executed at run time.
  • LABEL: It is used to add labels to the docker image.

Creating the Dockerfile

In this section, we will create a dockerfile to build a LAMP server image from the Ubuntu base image.

First, you will need to create a directory to store the dockerfile. You can create it with the following command:

mkdir LAMP

Next, create a directory named Dockerfile inside the directory:

nano LAMP/Dockerfile

Add the following lines:

FROM ubuntu:latest
MAINTAINER Hitesh Jethva
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y && apt-get install apache2 mariadb-server
libapache2-mod-php php php-cli php-common php-mysql php-json php-curl -y
CMD ["apachectl","-D","FOREGROUND"]
EXPOSE 8080

Save and close the file when you are finished.

Building Image with Dockerfile

After creating the Dockerfile, you can easily create a custom LAMP image with the help of the Dockerfile.

First, change the directory to LAMP and run the following command to build the image from that file:

cd LAMP
docker build -t "lamp:Dockerfile".

The above command will start downloading the Ubuntu latest image from the Docker Hub and installed necessary packages specified in the Dockerfile. Once the image has been built successfully, you should see the following output:

Sending build context to Docker daemon  2.048kB
Step 1/6 : FROM ubuntu:latest
latest: Pulling from library/ubuntu
54ee1f796a1e: Pull complete
f7bfea53ad12: Pull complete
46d371e02073: Pull complete
b66c17bbf772: Pull complete
Digest: sha256:31dfb10d52ce76c5ca0aa19d10b3e6424b830729e32a89a7c6eee2cda2be67a5
Status: Downloaded newer image for ubuntu:latest
 ---> 4e2eef94cd6b
Step 2/6 : MAINTAINER Hitesh Jethva
 ---> Running in 047977af2c2a
Removing intermediate container 047977af2c2a
 ---> 1331df625c4c
Step 3/6 : ENV DEBIAN_FRONTEND=noninteractive
 ---> Running in 3597152c7a1b
Removing intermediate container 3597152c7a1b
 ---> 86c82c95e75d
Step 4/6 : RUN apt-get update -y && apt-get install apache2 mariadb-server
 libapache2-mod-php php php-cli php-common php-mysql php-json php-curl -y

Removing intermediate container 322532299fd9
 ---> f6897a9554f7
Step 5/6 : CMD ["apachectl","-D","FOREGROUND"]
 ---> Running in 669635bc8bcb
Removing intermediate container 669635bc8bcb
 ---> e8400eb2e677
Step 6/6 : EXPOSE 8080
 ---> Running in 937ae2b2d305
Removing intermediate container 937ae2b2d305
 ---> 2123a857361d
Successfully built 2123a857361d
Successfully tagged lamp:Dockerfile

You can now list your newly build an image by running the following command:

docker images

You should see the following output:

REPOSITORY    TAG       IMAGE        ID    CREATED      SIZE

lamp      Dockerfile  2123a857361d   44    seconds ago   520MB

ubuntu     latest     4e2eef94cd6b   8     days ago      73.9MB

Now, you have a custom LAMP server image in your hand. You can also see the history of each command with the following command:

docker history lamp:Dockerfile

You should see the following output:

IMAGE               CREATED             CREATED BY                                      SIZE   COMMENT
2123a857361d        16 minutes ago      /bin/sh -c #(nop)  EXPOSE 8080                  0B                  
e8400eb2e677        16 minutes ago      /bin/sh -c #(nop)  CMD ["apachectl" "-D" "FO…   0B                  
f6897a9554f7        16 minutes ago      /bin/sh -c apt-get update -y && apt-get inst…   446MB              
86c82c95e75d        17 minutes ago      /bin/sh -c #(nop)  ENV DEBIAN_FRONTEND=nonin…   0B                  
1331df625c4c        17 minutes ago      /bin/sh -c #(nop)  MAINTAINER Hitesh Jethva     0B                  
4e2eef94cd6b        8 days ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B

Creating a Container from LAMP Image

Now, you can run a container from your image using the following command:

docker run -dit lamp:Dockerfile

Once the container has been started, you should see the following output:

0d2beb7dba01bb763768b116f734ae68286cee00d2ae923b2b7241c39ad54208

You can verify the running container using the following command:

docker ps

You should get the following output:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
c14794784eb2        lamp:Dockerfile     "apachectl -D FOREGR…"   2 minutes ago       Up 2 minutes        0.0.0.0:8080->8080/tcp   quirky_ramanujan

Conclusion

In this guide, you learned what is Dockerfile and how to build a docker image with Dockerfile. This is very useful for creating your custom images instead of committing changes to a pulled image.

About the author

Hitesh Jethva

Hitesh Jethva

I am Hitesh Jethva lives in Ahmedabad, INDIA. I am Linux system administrator and Technical writer.

I felt in love with Linux while i was started to learn Linux. I am a fan of open source technology and have more than 8+ years of experience in Linux and Open Source technologies. My main motto is to make uncomplicated things easier.

I have extensive experience within the following areas: CentOS/RHEL/FreeBSD/Ubuntu/Debian, cPanel/WHM, High Availability Architecture, Proactive security/Web Application Security, Amazon Web Services (AWS), Apache/Nginx, OpenLDAP, DevOps automation: Chef/Docker.

My expertise includes Linux system administration, installation, configuration, tuning, security and troubleshooting. I have large skills in configuring/management/support of Apache, Nginx, MariaDB, MongoDB, PHP-FPM, Nagios, Zabbix, Graylg, Redis, Docker and much more.