Docker Tips: All About the Build Context

Understand what the build context is and how to optimize it

Luc Juggery
Oct 19, 2018 · 5 min read
Let’s check out this build context thing!

What Is the Build Context?

Let’s start with the command used to build a Docker image:

The build context is the set of files located at the specified PATH or URL. Those files are sent to the Docker daemon during the build so it can use them in the filesystem of the image.

Let’s illustrate this.

Using a path

Let’s suppose I’m in the folder containing the source code of the genx application (simple Go application that generates dummy data).

Usually, we use a command like the following one to build the image, the Dockerfile being at the root of the project’s folder:

In that case, the build context is the content of the current folder (“.” specified as the last element of the command).

Using a URL

This same genx project is managed in GitLab, so it’s possible to build an image locally referencing the GitLab repository:

In that case, the build context is the set of files in .

Basically, the build context contains at least the application code which will be copied over to the image filesystem, but it often contains many other things we may or may not need in the image.


Should I Filter the Build Context?

Yes, we’d probably be better off making sure the build context only contains the files and folders it really needs.

In a project where source code is handled by Git, we use a file to make sure private data is kept locally and not sent out to GitHub/GitLab/BitBucket/etc.

The same thing applies during the build phase of a Docker image as the daemon uses a file to filter out the files and folders that should not be taken into account in the build context.


What if I Don’t Use a .dockerignore?

You would then send to the Docker daemon a lot of stuff that it does not need and which could be copied over to the image filesystem.

Huge file in the build context

Let’s consider the following Dockerfile. It uses a base image and copies the content of the current folder (index.html, css, js, img) into the default location served by NGINX (/usr/share/nginx/html).

The content of the current folder is like this:

Note: Did you notice the Ubuntu installation ISO in this folder (here by mistake)? When building the image, this huge guy is sent out to the daemon and copied over to the image… obviously, not something we want.

The current folder content is sent to the daemon (2G sent to the daemon and copied in an image layer)

Note: I do not recommend following this example. The Docker daemon does not really like it… at all. (I even needed to restart it on my MacBook Pro afterward).

But, in case we really need this file here (just for fun), we just have to create a file and add its name in it. We should add just in case we download other ISOs.

Doing so, we can be sure no ISO file will be sent to the daemon.

OK, it’s not likely that a 2 GB ISO file will be present in the current folder but… what about the Git history of the project, which can also be quite huge?

Git history

Let’s remove the ISO file and start handling this project with Git.

We then create the image:

And check what’s inside:

The folder, containing the versioning history of the projects which can be a huge folder, is there. Do we need the whole Git history in the image? Don’t think so. We should then create a and add inside.

Credentials

Let’s say I work on a Node.js application that needs to connect to an external MongoDB database.

When the application is deployed on a swarm or on a Kubernetes cluster, it is advised to provide the connection string via a secret. (You might be interested in this article if you want to know more: From env variables to Docker secrets.)

But, during the development phase, we might have those credentials in the current folder to test the application.

What about having a folder in our project? That’s pretty ugly but that could help, right? Well, at least if we make sure it’s not replicated everywhere.

I have the following file, no problem, my password will not go to GitHub:

But, I do not have any . My credential files will then be shipped over into the image.

We should have created a file and added the name of the folder we do not want to expose () in it.


Summary

Those simple (and exaggerated) examples show that filtering the content of the build context with a file is very simple and very important, too. Do you always make sure your build context is correctly handled?

Better Programming

Advice for programmers.

Luc Juggery

Written by

#DockerCaptain #Startups #Software #中文学生 Learning&Sharing

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade