This page is under regular updates. Please check back later for more content.
Container Images

Creating Image

There are two main approaches to creating an image -

  • Using a running container: a container is started, and modifications are applied to the container. The docker commit command is used to write modifications

Must cleanup before creating image. For example - you have installed some pckages and you didn't deleted those packages then the image size will be more than 100MB or more

  • Using a Dockerfile: a Dockerfile contains instructions for building an image. Each instruction adds a new layer to the image, which offers more control over the files that are added to an image at a later stage

Image creation terminology

  • Dockerfile is the original terminology, which was introduced by Docker
  • OCI has standardized the name to Containerfile
  • Feel free to use either of these file names

Understanding parent/child Images

  • When working with Dockerfile, using Parent/Child images is common
  • A child image is an image that is created from a parent image and incorporates everything in the parent image
  • Starting from a parent image makes it easier to create a reliable image

Understanding the Process

  • First, you'll create a working directory: each project should have its own project directory
  • Next, you'll write the Dockerfile: the Dockerfile contains instructions to build the image
  • Finally, build the image with docker

Writing a dockerfile

Each Dockerfile starts with FROM, identifying the base image to use

Next, instructions are executed in that base image

  • Instructions are executed in the order specified
  • Each Dockerfile instruction runs in an independent container, using an intermediate image built from a previous command, which means that adding multiple instructions results in multiple layers

Adding multiple layers to an image will increase the size of image, so it is recommended to have minimum layer possible while creating your image

Dockerfile instruction

  • FROM identifies the base image to use
  • LABEL is a key-value pair that is used for identification
  • MAINTAINER is the name of the person that maintains the image
  • RUN executes commands on the FROM image while building the image
  • EXPOSE has metadata-only information on where the image should run
  • ENV defines environment variables to be used within the container
  • ADD copies files from the project directory to the image
  • COPY copies files from the local project directory, using ADD is preferred
  • USER specifies username for RUN, CMD and ENTRYPOINT instructions
  • ENTRYPOINT has the standard command that the image will run (cannot be overridden by user)
  • CMD can have the standard command, as well as arguments to the ENTRYPOINT command (canbe overridden by user)

Understanding ENTRYPOINT

ENTRYPOINT is the default command to be processed. If not specified, /bin/sh -c is executed as the default command Arguments to the ENTRYPOINT command should be specified separately using CMD

  • ENTRYPOINT ["command"]; ENTRYPOINT ["/usr/sbin/httpd"]
  • CMD ["argl","arg2"]; CMD [-D", "FOREGROUND"]

If the default command is specified using CMD instead of ENTRYPOINT, the command is executed as an argument to the default entrypoint sh -c which can give unexpected results

If the arguments to the command are specified within the ENTRYPOINT, then they cannot be overwritten from the command line; so to make your Dockerfile flexible, make sure to pass the command arguments separately in a CMD section

Understanding ADD or COPY

  • ADD and COPY are doing the same thing

  • COPY is simpler and has less features

  • ADD has specific features

    • ADD can directly extract the contents of a tar file into the container
    • ADD can fetch files from a URL, but this is deprecated. Rather, use RUN wget to fetch the file, and delete them afterwards when the file is no longer needed

Understanding formats

Options like ADD, COPY, ENTRYPOINT, CMD are used in shell form and in exec form

  • Shell form is a list of items
    • ADD /my/file /mydir
    • ENTRYPOINT /usr/bin/nmap -sn 172.17.0.0/24
  • Exec form is a JSON array of items
    • ADD ["/my/file", "/mydir"]
    • ENTRYPOINT ["/usr/bin/nmap", "-sn", "172.17.0.0/24"]

Using Exec form is preferred, as shell form wraps command in a /bin/sh -c shell, which creates a sometimes unnecessary shell process

Avoiding multi-layer Image

Each command used in a Dockerfile creates a new layer and this should be avoided. So don't run multiple RUN commands, connect them using &&

For example -

RUN yum --disablerepo=* --enablerepo="myrepo" && yum update -y && yum install nmap

  • To maintain readability, write the commands on different lines using && \ at the end of each line:
RUN yum --disablerepo=* && \
    yum update -y && \
    yum install -y nginx

Building Image with Dockerfile

Use docker build -t nmap . to run it from the current directory.

Tip: use docker build --no-cache -t nmap . to ensure the complete procedure is performed again

Next, use docker run nmap to run it. For troubleshooting - docker run -it nmap /bin/bash. Will only work if you've installed bash!

Using docker commit

After making changes to a container, you can save it to an image. Use docker commit to do so.

  • docker commit -m "custom web server" -a "Sandervan Vugt" myapache myapache
  • Use docker images to verify

Next, use docker save -o myapache.tar myapache and transport it to anywhere you'd like. From another system, use docker load -i myapache.tar to import it as an image.