3 Different Ways to Provide Docker Build Context

Docker Commands

Reading Time: 6 minutes

One of the powerful things about Docker is that it is possible for someone to use Docker every day without ever having to create their own custom container. In today’s article, we are going to explore a few uncommon ways to build a Docker container.

The docker build command has many options that can be considered uncommon or only used for special situations. In this article, we are specifically going to focus on different ways to provide the docker build command a source or context to build from.

To explain this better, let’s first explore the traditional build approach.

Traditional Approach

The traditional build approach essentially consists of executing the docker build command within a directory that contains a Dockerfile. Let’s see this approach in action with the below example.

$ docker build -t automatron .
Sending build context to Docker daemon  4.368MB
Step 1/9 : FROM ubuntu:14.04
 ---> 3f755ca42730
Step 2/9 : RUN apt-get update --fix-missing &&     apt-get -y upgrade &&     apt-get -y install     python-pip     python-dev     nmap     curl     libffi-dev     build-essential     libssl-dev
 ---> Using cache
 ---> 901e767bce5a
Step 3/9 : ADD requirements.txt /
 ---> Using cache
 ---> d8e0c2f89a72
Step 4/9 : RUN pip install --upgrade setuptools
 ---> Using cache
 ---> d62382ab676f
Step 5/9 : RUN pip install -r /requirements.txt
 ---> Using cache
 ---> cca17f716d3d
Step 6/9 : RUN pip install honcho
 ---> Using cache
 ---> 62293cc90b19
Step 7/9 : ADD . /
 ---> Using cache
 ---> 808d0bdf961d
Step 8/9 : RUN find -name "*.sh" -exec chmod 755 {} \;
 ---> Using cache
 ---> 353248eb9652
Step 9/9 : CMD honcho start
 ---> Using cache
 ---> 0c650b43b3d4
Successfully built 0c650b43b3d4
Successfully tagged automatron:latest

During the docker build execution shown above, we specify two options. The first being the -t flag; as we explored in an earlier article, the -t flag is used to “tag” or name the resulting image. In the example above, we simply named the container automatron.

The second option is .; this option is the context or source that the docker build command should use during the build. By specifying ., we are specifying that Docker should execute the build using the current working directory as the context. What this means is that docker build will look for a Dockerfile (the instruction file for building containers) within the specified directory.

If we were to execute this command from one directory higher, our command would look like the following example:

$ docker build -t automatron automatron/
Sending build context to Docker daemon  4.368MB
Step 1/9 : FROM ubuntu:14.04
 ---> 3f755ca42730
Step 2/9 : RUN apt-get update --fix-missing &&     apt-get -y upgrade &&     apt-get -y install     python-pip     python-dev     nmap     curl     libffi-dev     build-essential     libssl-dev &&     rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> 901e767bce5a
Step 3/9 : ADD requirements.txt /
 ---> Using cache
 ---> d8e0c2f89a72
Step 4/9 : RUN pip install --upgrade setuptools
 ---> Using cache
 ---> d62382ab676f
Step 5/9 : RUN pip install -r /requirements.txt
 ---> Using cache
 ---> cca17f716d3d
Step 6/9 : RUN pip install honcho
 ---> Using cache
 ---> 62293cc90b19
Step 7/9 : ADD . /
 ---> Using cache
 ---> 808d0bdf961d
Step 8/9 : RUN find -name "*.sh" -exec chmod 755 {} \;
 ---> Using cache
 ---> 353248eb9652
Step 9/9 : CMD honcho start
 ---> Using cache
 ---> 0c650b43b3d4
Successfully built 0c650b43b3d4
Successfully tagged automatron:latest

The commands above should be familiar to anyone who regularly builds custom Docker containers. However, the approach above is not the only way we can pass context to the docker build command.

Building From a Git Repository

In the above example, we built a container for the open-source project Automatron. Since this is a project hosted on GitHub and this project contains a Dockerfile in its top level directory, we can streamline this docker build process by building directly from the Git repository.

$ docker build -t automatron https://github.com/madflojo/automatron.git
Sending build context to Docker daemon  1.938MB
Step 1/9 : FROM ubuntu:14.04
 ---> 3f755ca42730
Step 2/9 : RUN apt-get update --fix-missing &&     apt-get -y upgrade &&     apt-get -y install     python-pip     python-dev     nmap     curl     libffi-dev     build-essential     libssl-dev
 ---> Using cache
 ---> 956f75f19219
Step 3/9 : ADD requirements.txt /
 ---> Using cache
 ---> 23a02980ee87
Step 4/9 : RUN pip install --upgrade setuptools
 ---> Using cache
 ---> 36069877f17b
Step 5/9 : RUN pip install -r /requirements.txt
 ---> Using cache
 ---> 083745ce4316
Step 6/9 : RUN pip install honcho
 ---> Using cache
 ---> 2bd024e0890d
Step 7/9 : ADD . /
 ---> 58b5b6d021c7
Removing intermediate container d3b2db67817f
Step 8/9 : RUN find -name "*.sh" -exec chmod 755 {} \;
 ---> Running in 5e0d91149c94
 ---> 53f04392979a
Removing intermediate container 5e0d91149c94
Step 9/9 : CMD honcho start
 ---> Running in 9cd301a364cf
 ---> fb62cbb68063
Removing intermediate container 9cd301a364cf
Successfully built fb62cbb68063
Successfully tagged automatron:latest

In the first example, the traditional build method. We had a copy of the Automatron project cloned to our local system. When we executed the build, we did so using a local directory. In the example above, building from a Git repository. We simply use the Git repository URL as the context for the docker build command.

When executed in this manner, Docker will clone the remote Git repository and perform the build using the cloned repository as its context.

!Sign up for a free Codeship Account

Understanding Build Context

When talking about Docker builds, context means the source directory used when building the container. To explain this a bit better, let’s look at the docker build output.

Step 3/9 : ADD requirements.txt /
 ---> Using cache
 ---> 23a02980ee87
Step 4/9 : RUN pip install --upgrade setuptools
 ---> Using cache
 ---> 36069877f17b
Step 5/9 : RUN pip install -r /requirements.txt
 ---> Using cache
 ---> 083745ce4316

In both the traditional and Git examples, these lines were part of the build output. These are Docker build steps that are specified within the Automatron Dockerfile.

The first step (step 3 of 9) is ADD requirements.txt /. This step will add the requirements.txt file into the Docker container image being built.

In the first example, the traditional local directory approach. The requirements.txt was copied from the local directory (the context directory) into the Docker container. This is the type of functionality we are used to with a basic build.

Where the second example — the Git example — differs is that the Git repository is used as the context directory. What this means is that when the ADD instruction executed, it added the requirements.txt file from the Git repository itself, not the local directory.

To explain this a little better, even if I have a requirements.txt file in the current working directory, the requirements.txt that is added will not be from my local directory, but rather the requirements.txt hosted on the Git repository.

This is an important concept to understand not only for this article, but when building Docker containers in general. As many times when troubleshooting why the ADD or COPY instructions fail, it is often they are trying to reference something outside of the build context.

Building From a Tar File

In addition to building containers using a remote Git repository, the docker build command is also able to take remote TAR files as build context.

Let’s take a look at this in action to get a better understanding.

$ docker build -t automatron http://example.com/automatron.tar.gz
Step 1/9 : FROM ubuntu:14.04om remote url: http://example.com/automatron.tar.gz [==================================================>]  2.418MB/2.418MB
---> 3f755ca42730
Step 2/9 : RUN apt-get update --fix-missing &&     apt-get -y upgrade &&     apt-get -y install     python-pip     python-dev     nmap     curl     libffi-dev     build-essential     libssl-dev &&     rm -rf /var/lib/apt/lists/*
---> Using cache
---> 901e767bce5a
Step 3/9 : ADD requirements.txt /
---> Using cache
---> 67206f314a21
Step 4/9 : RUN pip install --upgrade setuptools
---> Using cache
---> ea61de8843be
Step 5/9 : RUN pip install -r /requirements.txt
---> Using cache
---> bdefd81afb47
Step 6/9 : RUN pip install honcho
---> Using cache
---> 16c4ca480eca
Step 7/9 : ADD . /
---> Using cache
---> 8cce790d2b46
Step 8/9 : RUN find -name "*.sh" -exec chmod 755 {} \;
---> Using cache
---> 3a9f60aadff7
Step 9/9 : CMD honcho start
---> Using cache
---> 7e95852e0e16
Successfully built 7e95852e0e16
Successfully tagged automatron:latest

The above docker build execution is similar to the Git example except for one difference. Rather than the target context being a Git repository, it is a remote TAR file. I am specifying that the TAR file is remote because the docker build command (at the time of this article) does not support using a local TAR file as the build context.

What it does support is downloading a TAR file via HTTP, extracting that TAR, and using its contents for the build context directory. In the example above, the TAR file was compressed using gzip; the docker build command currently supports both the bzip and gzip compression formats.

Summary

In this article, we explored three different ways to provide build context to the docker build command. These methods can be useful when the container to be built is provided via a TAR or Git repository, as executing the builds by specifying the remote location can save several execution steps.

Subscribe via Email

Over 60,000 people from companies like Netflix, Apple, Spotify and O'Reilly are reading our articles.
Subscribe to receive a weekly newsletter with articles around Continuous Integration, Docker, and software development best practices.



We promise that we won't spam you. You can unsubscribe any time.

Join the Discussion

Leave us some comments on what you think about this topic or if you like to add something.