Different Instructions in a Dockerfile and their usage

Learn about different components/Instructions that makes a Dockerfile

What is Dockerfile?

The set of instructions for building a container are written in Dockefile. It is a text file that contains the base image, all the settings, and the list of commands required for preparing and starting a container.


Dockerfile basic Example

A basic example of a Dockerfile for installaing and building a apache web server.
FROM centos:latest

MAINTAINER admin

RUN yum update && yum -y install httpd

RUN echo "Hello, Welcome to the world of Dockers" > /var/www/html/index.html

EXPOSE 80

CMD [“/usr/sbin/httpd”, “-D”, “FOREGROUND”]

Instructions in Dockerfile

The syntax of Dockerfile is simple and contains below instructions:

FROM:

FROM is the first instruction in any Dockerfile and it defines the base image to use. Base image can be any existing Docker image, typically it is operating system image or a specific application framework.
Usage:
FROM <image>
FROM <image>:<tag>

MAINTAINER:  [deprecated]

It is used to set the author of that image. You can do same task using LABEL instruction.
Usage:
MAINTAINER <name>

RUN:

RUN is used to run or execute commands in the container. Usage of RUN is RUN <command> , command is run in a shell, which is by default /bin/sh –c
Usage:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh –c)

ADD:

ADD is used to copy the files, directories, remote file URLs from current directory into the container. Eg ADD <src><dest>.
<src> file can also be tar archive, the same will be unpacked for you as a directory into the docker image.
If <dest> path do not exist, it will be created for you.
Usage:
ADD <src><dest>

COPY:

It is similar to ADD, but it do not support the compression and URL file functionality. It is used to copy the files or directories from <src> and adds them to the destination path.
Usage:
COPY <source>… <destination>

CMD:

When container starts up, these commands will be executed/run. It is used to provide defaults for an executing container. The defaults can be executables or in case executable is omitted/excluded then you must specify an ENTRYPOINT instruction as well. In case there are more than one CMD in the dockerfile, then only the last CMD will take effect.
In case a user specify any arguments to docker run, then they will override the defaults mentioned in CMD.
Usage :
CMD [“executable”,”param1″,”param2″]  (exec form)
CMD [“param1″,”param2”] (default parameters to ENTRYPOINT)

LABEL:

It is used to add metadata to an image. A label is a key-value pair. An image can have more than one label. You can view image labels using docker inspect command.
Eg of Label:
LABEL version=”1.0″

EXPOSE:

It is used to inform Docker that container listens on the specified network port at the runtime. You can specify the protocol as well (TCP or UDP), by default  TCP is the protocol if nothing is specified.
Using EXPOSE,  the ports are exposed and can be used to publish and map one or more ports using –p option with docker run.
Regardless, of the EXPOSE instruction, the settings can be override at runtime by using the –p flag.
For eg.
docker run –p 80:80/tcp –p 5050:5050 ….
Usage:
 EXPOSE <port> [<port>/<protocol>…]

ENV:

The ENV instruction is used  to set the environment variable <key> to the value <value>
First format given in usage below will set single variable to value, while the second format can be used to set multiple variables at one time. You can view all the set environment variables using docker inspect command and change them using dockerrun –env<key>=<value>
Usage:
ENV <key><value>
ENV <key>=<value> …

ENTRYPOINT:

ENTRYPOINT allows you to configure a container that will run as an executable.

What’s the difference between CMD and ENTRYPOINT

Docker has default entrypoint (/bin/sh -c) but does not have a command. For example, running below <docker run image>, here the default Entrypoint will be /bin/sh -c and CMD will be bash. So that means, CMD is run via the ENTRYPOINT or CMD will be the parameter of the entrypoint.
Docker run –i –t ubuntu bash
Entrypoint : /bin/sh –c
Cmd : bash
Another example, suppose you want to use ENTRYPOINT as /bin/cat. So, when docker run image /etc/passwd command will run /etc/passwd is command and it is passed to the ENTRYPOINT /bin/cat and the execution is /bin/vat /etc/passwdd
Final Conclusion is ENTRYPOINT specifies a command that will always be executed when container starts.
CMD specifies arguments that will be fed to the ENTRYPOINT
Usage:
ENTRYPOINT [“executable”, “param1”, “param2”] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)

VOLUME:

Volume defines a path or creates a mount point in the container that Docker exposes to the host system and it can be mapped using the -v option.
The docker run command initializes the specified volume along with the existing data in the volume within the base image.
Usage:
VOLUME [“/path”]
VOLUME  /path1 /path2 ..

USER:

USER instruction sets the username or UID to use while running the image. Also, GID or user group can also be specified with USER instructions.
Usage:
USER <user>[:<group>]
USER <UID>[:<GID>]

WORKDIR:

The WORKDIR instruction is used to set the working directory for any ADD, COPY, CMD, RUN or ENTRYPOINT instruction that follows it. It can be used multiple times in a Dockerfile.
Usage:
WORKDIR </path>

ARG:

ARG instruction is used to define a variable that can be passed at build time to the builder docker build using the –build-arg <variable>=<value>
A dockerfile can contain multiple ARG instructions. Environment variable defined using ENV instruction always override the ARG instruction.
It is not recommended to pass user credentials, github keys as build time variables as the same will be visible in docker history command.
Usage:
ARG <name>[=<default value>]

SHELL:

SHELL instruction is particulary useful for Windows and it allows to override the default shell (/bin/sh -c) for Linux and (“cmd” “/S”, “/C” ).
SHELL instruction also allows to use alternate shells like zsh, tsh, powershell etc.
Usage:
SHELL [“<executable>”, “<param1>”, “<param2>”]
Please comment down your thoughts on Dockerfiles and let us know if you have any query.