Skip to content

Instantly share code, notes, and snippets.

@fabiomolinar
Last active September 1, 2018 12:09
Show Gist options
  • Save fabiomolinar/6065f8616e99a5e77906bddf0e696458 to your computer and use it in GitHub Desktop.
Save fabiomolinar/6065f8616e99a5e77906bddf0e696458 to your computer and use it in GitHub Desktop.
Summary of chapter 3 from the book "Learning Docker"

Dockerfile cheat sheet

Source:

  • Learning Docker (Chapter 3)
  • Author: Jeeva S. Chelladhurai, Vinod Singh, Pethuru Raj

As we discussed in the previous chapter, we can craft an image manually by launching a container from a base image, install all the required applications, make the necessary configuration file changes, and then commit the container as an image. As a better alternative, we can resort to the automated approach of crafting the images using Dockerfile, which is a text-based build script that contains special instructions in a sequence for building the correct and relevant images from the base images. The sequential instructions inside Dockerfile can include selecting the base image, installing the required application, adding the configuration and the data files, and automatically running the services as well as exposing those services to the external world. Thus, the Dockerfile-based automated build system has simplified the image-building process remarkably. It also offers a great deal of flexibility in organizing the build instructions and in visualizing the complete build process.

The Docker Engine tightly integrates this build process with the help of the docker build subcommand.

Command to build a container from a Dockerfile file is as follows:

$ sudo docker build -t <repository name>:<tag number/name> -f <path to Dockerfile>

This command is just going to build the container. It won't start the container automatically. Therefore, after building the container, we need to use the following command to start the container:

$ sudo docker run <container ID>

Syntax

Syntax structure:

# Comment
INSTRUCTION arguments 

Instructions

  • FROM

The FROM instruction is the most important one and is the first valid instruction of a Dockerfile. It sets the base image for the build process. Subsequent instructions will use this base image and build on top of it.

The FROM instruction has the following syntax:

FROM <image>[:<tag>|@<digest>]

  • MAINTAINER

The MAINTAINER instruction is an informational instruction of a Dockerfile. This instruction capability enables the authors to set the details in an image. Docker does not place any restrictions on placing the MAINTAINER instruction in Dockerfile. However, it is strongly recommended that you place it after the FROM instruction. The following is the syntax of the MAINTAINER instruction, where <author's detail> can be in any text.

MAINTAINER <author's detail>

Example:

MAINTAINER Fabio Molinar <fabiomolinar@gmail.com>

  • COPY

The COPY instruction enables you to copy the files from the Docker host to the filesystem of the new image. The following is the syntax of the COPY instruction:

COPY <src> ... <dst>

Where:

- <src>: This is the source directory, the file in the build context, or the directory from where the docker build subcommand was invoked.
- ...: This indicates that multiple source files can either be specified directly or be specified by wildcards.
- <dst>: This is the destination path for the new image into which the source file or directory will get copied. If multiple files have been specified, then the destination path must be a directory and it must end with a slash (/).asd
  • ADD

The ADD instruction is similar to the COPY instruction. However, in addition to the functionality supported by the COPY instruction, the ADD instruction can handle the TAR files and remote URLs. We can annotate the ADD instruction as COPY on steroids.

It has the same syntax as COPY.

  • ENV

The ENV instruction sets an environment variable in the new image. An environment variable is a key-value pair, which can be accessed by any script or application. Linux applications use the environment variables a lot for a starting configuration. The following line forms the syntax of the ENV instruction:

ENV <key> <value>

Environment variables can be used within other instructions!

Example:

ARG BUILD_VERSION 
LABEL com.example.app.build_version=${BUILD_VERSION}  
  • ARG

The ARG instruction lets you define variables that can be passed during the Docker image build time. The Docker build subcommand supports the --build-arg flag to pass a value to the variables defined using the ARG instruction. If you specify a build argument that was not defined in your Dockerfile, the build would fail. In other words, the build argument variables must be defined in the Dockerfile to be passed during the Docker image build time. The syntax of the ARG instruction is as follows:

ARG <variable>[=<default value>]

Example:

ARG usr 
ARG uid=1000
  • USER

The USER instruction sets the startup user ID or username in the new image. By default, the containers will be launched with root as the user ID or UID. Essentially, the USER instruction will modify the default user ID from root to the one specified in this instruction. The syntax of the USER instruction is as follows:

USER <UID>|<UName>

Though it is recommended that you have a valid user ID to match with the /etc/passwd file, the user ID can contain any random numerical value. However, the username must match with a valid username in the /etc/passwd file, otherwise, the docker run subcommand will fail and it will display the following error message:

finalize namespace setup user get supplementary groups Unable to find user

  • WORKDIR

The WORKDIR instruction changes the current working directory from / to the path specified by this instruction. The ensuing instructions, such as RUN, CMD, and ENTRYPOINT will also work on the directory set by the WORKDIR instruction. The following line gives the appropriate syntax for the WORKDIR instruction:

WORKDIR <dirpath>

  • VOLUME

The VOLUME instruction creates a directory in the image filesystem, which can later be used for mounting volumes from the Docker host or the other containers.

  • EXPOSE

The EXPOSE instruction opens up a container network port for communicating between the container and the external world. The syntax of the EXPOSE instruction is as follows:

EXPOSE <port>[/<proto>] [<port>[/<proto>]...]

Where:

- <port>: This is the network port that has to be exposed to the outside world.
- <proto>: This is an optional field provided for a specific transport protocol, such as TCP and UDP. If no transport protocol has been specified, then TCP is assumed to be the transport protocol.

The following is an example of the EXPOSE instruction inside a Dockerfile exposing the 7373 port number as a UDP port and the 8080 port number as a TCP port. As mentioned earlier, if the transport protocol has not been specified, then the TCP transport is assumed to be the transport protocol:

EXPOSE 7373/udp 8080

  • LABEL

The LABEL instruction enables you to add key-value pairs as metadata to your Docker images. These metadata can be further leveraged to provide meaningful Docker image management and orchestration. The syntax of the LABEL instruction is as follows:

LABEL <key-1>=<val-1> <key-2>=<val-2> ... <key-n>=<val-n>

Docker recommends using namespaces to label keys using the reverse domain notation.

That is done to avoid naming conflits.

  • RUN

The RUN instruction is the real workhorse during the build, and it can run any command. The general recommendation is to execute the multiple commands using one RUN instruction. This reduces the layers in the resulting Docker image because the Docker system inherently creates a layer for each time an instruction is called in Dockerfile.

RUN <command>

  • CMD

The CMD instruction can run any command (or application), which is similar to the RUN instruction. However, the major difference between these two is the time of execution. The command supplied through the RUN instruction is executed during the build time, whereas the command specified by the CMD instruction is executed when the container is launched from the newly created image.

  • ENTRYPOINT
  • HEALTHCHECK
  • ONBUILD
  • STOPSIGNAL
  • SHELL

.dockerignore

The .dockerignore file is a newline-separated TEXT file, wherein you can provide the files and the directories which are to be excluded from the build process. The exclusion list in the file can have both the fully specified file/directory name and the wildcards.

Complete Dockerfile example

FROM ubuntu
MAINTAINER Kimbro Staken 

RUN apt-get install -y python-software-properties python python-setuptools ruby rubygems
RUN add-apt-repository ppa:chris-lea/node.js
RUN echo "deb http://us.archive.ubuntu.com/ubuntu/ precise universe" >> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y nodejs 

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
RUN echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" | tee -a /etc/apt/sources.list.d/10gen.list
RUN apt-get -y update
RUN apt-get -y install mongodb-10gen

RUN easy_install supervisor
RUN echo_supervisord_conf > /etc/supervisord.conf
RUN printf "[include]\nfiles = /var/www/Supervisorfile\n" >> /etc/supervisord.conf

ADD . /var/www

RUN cd /var/www ; npm install 

CMD ["/usr/local/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"] 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment