Dockerfile is a text-based build script, composing of various instructions that contains special instructions in a sequence for building the images from the base images. The instructions inside the Dockerfile can include the base image selection, installing the required application, adding the configuration and the data files, and automatically running the services thus exposing those services to the outside world. Dockerfile is mainly used to automate the whole image building process. The Docker engine integrates this build process by using the docker build subcommand. Docker daemon is responsible for the complete build process and the Docker command line interface is responsible for Dockerfile to daemon.
In this tutorial, we will discuss basic dockerfile syntax, dockerfile commands, converting the Dockerfile into an image and launch container from that image.
A Dockerfile is made up of instructions, comments, and empty lines. as shown below:
## Comment INSTRUCTION arguments
The instruction line is made up of two components instruction and arguments. The instruction could be written in uppercase in order to differentiate it from the arguments. For example:
This is my Dockerfile FROM ubuntu:14.04 CMD echo Welcome to Docker!!
Here FROM is an instruction, ubuntu:14.04 is an argument and CMD is an instruction, "echo Welcome to Docker!!" is an argument
The comment line in Dockerfile must begin with # symbol. The docker build system ignores any empty lines and lines beginning with a # symbol.
Dockerfile Build Instructions
In this section, we will discuss the Dockerfile commands, their syntex and some examples. There are lot's of commands which Dockerfiles can contain to have docker build an image.
Let's now take a look at various Dockerfile commands (instructions) and their usage.
The FROM directive is the most important command for Dockerfiles. It sets the base image for the build process. The subsequent commands would use this base image and build on top of it. The docker build system first looks in the Docker host for the images, if the image is not found in the Docker host, then the docker build system will pull the image from the Docker Hub Registry.
The FROM directive has the following syntax:
imagename : This is the name of the image which will be used as the base image. tag : it specify the version of image. If any tag has not been specified, then the tag latest is assumed.
Here, the FROM instruction with the image name ubuntu and the tag 14.04
Docker also allows multiple FROM instructions in a single Dockerfile to create multiple images. The Docker build system will pull all the images specified in the FROM instruction.
The MAINTAINER directive is an informational instruction of a Dockerfile. It enables the authors to set the details in an image. You can set this directive anywhere in the Dockerfile. However, it is recommended to place it after the FROM directive.
Here, sample syntax of the MAINTAINER directive is:
For example the MAINTAINER directive with the author name and the E-mail address:
MAINTAINER hitesh jethva
The ADD Directive
The ADD directive is used to copy the file from the Docker host to the filesystem of the new image.
You should see the sample syntax of ADD directive in following line:
: This is the source path of the Docker host system. This is the destination path for the Docker image into which the source file or directory will get copied.
For example, we will copy the website directory from the Docker host to /var/www/html/ , which is in the Docker image filesystem:
ADD website /var/www/html
The ENV Directive
The ENV directive is used to set an environment variable in the Docker image. An environment variable can be accessed by any script or application. The Linux applications use the environment variables for a starting configuration.
The following line shows the syntax of the ENV directive:
: This is the environment variable
- This is used set for the environment variable
For example, you can set environment variable for APACHE_CONFIG to /etc/apache2 as below:
ENV APACHE_CONFIG /etc/apache2
The USER Directive
The USER directive is used to set the start up user ID in the new Docker image. BY default, the container will be launched with root user. You can modify the default user ID from root to the one specified in this directive.
You can see the syntax of the USER directive as follows:
USER UID | UserName
UID : This is a user ID UserName : This is a valid username.
For example, you can set the default UID to 1001 and username to hitesh as follows:
USER 1001 | hitesh
Note: The Username and UID must match with a valid user name and UID in the /etc/passwd file, otherwise the docker run subcommand will fail.
The WORKDIR Directive
The WORKDIR directive changes the current working directory from / to the path specified by this directive. This is used to set the currently active directory for other instructions such as RUN, CMD, ENTRYPOINT, COPY and ADD.
You can see the syntax of the WORKDIR directive as follows:
: This the path for the working directory to set in. The path can be either absolute or relative. If the specified directory is not found in the target image filesystem, then the directory will be created.
The VOLUME Directive
The VOLUME directive creates a directory in the Docker image filesystem, which can later be used for mounting volumes from the Docker host or the other containers.
The sample syntax for VOLUME directive as shown here:
In the above line, /Data is the mount point that has to be created in the new image.
The EXPOSE Directive
The EXPOSE directive can be used to opens up a container network port for communicating between the container and the outside world.
The sample syntax of the EXPOSE instruction is as follows:
EXPOSE [/] [[/]...]
: This is the network port that has to be exposed to the outside world.
- This is an optional field provided for a specific transport protocol, such as TCP and UDP.
The EXPOSE directive also allows you to specify multiple ports in a single line. You can expose the port number 8080 as a UDP port and the port number 80 as a TCP port is as follows:
EXPOSE 8080/udp 80/tcp
The RUN Directive
The RUN instruction is used during the build time, and it can run any command. This directive lets you execute a command on top of an existing layer and create a new layer with the results of command execution.
The sample syntax for RUN instruction is as follows:
[command] : The is the shell command has to be executed during the image build time
RUN [, ,....]
: This is the executable to run during the build time.
- This is the variables number of the arguments for the executable.
For example, you can user RUN directive with command apt-get as follows:
RUN apt-get install apache2
This will install the Apache package in Docker image.
The CMD Directive
The CMD directive is similar to the RUN directive. The major difference between CMD and RUN is that the RUN instruction is executed during the build time, whereas the CMD instruction is executed when the container is launched from the newly created image. You can add more than one CMD instruction in Dockerfile. However, only the last CMD instruction would be effective.
The sample syntax for CMD instruction is as follows:
[command] : The is the shell command has to be executed during the launch of the container.
CMD [, ,....]
: This is the executable, which is to be run during the container launch time.
- This is the variables number of the arguments for the executable.
CMD "echo" "Hello World!"
The ENTRYPOINT Directive
The ENTRYPOINT directive can be used to set the primary command for the image. For example, if you have installed only one application in your image and want it to run whenever the image is executed, Then ENTRYPOINT directive will be used. The ENTRYPOINT directive is similar to CMD directive, both ENTRYPOINT and CMD give you a way to identify which executable should be run when a container is started from your image. If you want your image to be runnable without using docker run command line arguments, then ENTRYPOINT or CMD will be used. All the elements specified using CMD will be overridden, except the arguments. They will be passed to the command specified in ENTRYPOINT.
CMD "Hello World!" ENTRYPOINT echo
Creating a Dockerfile
Now, it's time to write our own Dockerfile. Let's see a practical example to better understand the layering in the Docker images.
For this purpose, let's create a Dockerfile which can be used to create a docker image to run Apache containers.
Create a text file called Dockerfile in your working directory and write the following content in it:
sudo nano Dockerfile
# Dockerfile to build Apache container images Based on Ubuntu
# Set the base image to Ubuntu:14.04 FROM ubuntu:14.04
#Defining the maintainer
MAINTAINER hitesh jethva
#Update the repository sources list
RUN apt-get update -y
#Install necessary packages for apache
RUN apt-get install apache2 apache2-utils -y
#Setting the default port for apache
# Setting the default container command
ENTRYPOINT [ "/usr/sbin/apache2ctl" ]
#Set default commands to be executed, or passed to the ENTRYPOINT
CMD [ "-D", "FOREGROUND" ]
Save and close the file.
Now, we are ready to create our first apache image with docker.
To do this, run docker build subcommand, as shown here:
sudo docker build -t apache .
Finally, let's visualise the layers in the Docker image by using the docker history subcommand:
sudo docker history apache
This will produce a detailed report on each layer of the apache Docker image, as shown here:
IMAGE CREATED CREATED BY SIZE COMMENT
c8a9e28548d2 8 minutes ago /bin/sh -c #(nop) CMD ["-D" "FOREGROUND"] 0 B
15853e3e0165 8 minutes ago /bin/sh -c #(nop) ENTRYPOINT