Skip to content

Docker - Building Files

Once you have created a Dockerfile with instructions for your image, the next step is to build the image using the docker build command.

This command builds a Docker image from a Dockerfile and a ‘context’. The context is the set of files at a specified location (PATH or URL), typically the directory containing the Dockerfile.

docker build [OPTIONS] PATH | URL | -
  • -t, --tag name:tag: Names and optionally tags the image in the ‘name:tag’ format. This is highly recommended for easy reference.
  • -f, --file path/to/Dockerfile: Specifies the path to the Dockerfile if it’s not named Dockerfile or not in the root of the context directory.
  • . (dot): Often used as the PATH argument, indicating the current directory as the build context.
  • --no-cache: Disables the build cache, forcing Docker to re-run every instruction.
  • --build-arg key=value: Sets build-time variables that can be used by ARG instructions in the Dockerfile.

Let’s assume you have the following simple Dockerfile in your current directory (.):

# Simple Dockerfile example
FROM ubuntu:22.04
LABEL maintainer="demo@example.com"
RUN apt-get update && apt-get install -y --no-install-recommends curl && apt-get clean && rm -rf /var/lib/apt/lists/*
CMD ["echo", "My custom image built successfully!"]

To build this image and tag it as myimage with version 0.1, you would run:

docker build -t myimage:0.1 .

Explanation:

  • docker build: The command to start the build process.
  • -t myimage:0.1: Tags the resulting image as myimage with the tag 0.1.
  • .: Specifies the current directory as the build context. Docker will look for Dockerfile here and send the contents of this directory (respecting .dockerignore) to the Docker daemon.

During the build, Docker executes each instruction in the Dockerfile sequentially:

  • It starts from the FROM instruction, potentially pulling the base image (ubuntu:22.04) if not present locally.
  • For each subsequent instruction (LABEL, RUN, CMD, etc.), Docker checks if it can reuse a cached layer from a previous build. If the instruction and its context haven’t changed, it uses the cache (making builds faster).
  • If a layer cannot be reused from cache (or cache is disabled), Docker executes the instruction, creating a new intermediate container, running the command (e.g., apt-get update ...), and committing the result as a new image layer.
  • You will see output indicating the step number, the instruction being executed, and the intermediate container ID.
  • Finally, if the build is successful, it tags the final layer with the name and tag you specified (myimage:0.1) and reports the final image ID.

Example output snippet:

Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM ubuntu:22.04
---> a7be6190844e
Step 2/4 : LABEL maintainer="demo@example.com"
---> Running in abcdef123456
---> 2f3a4b5c6d7e
Removing intermediate container abcdef123456
Step 3/4 : RUN apt-get update && apt-get install -y --no-install-recommends curl && apt-get clean && rm -rf /var/lib/apt/lists/*
---> Running in 123456abcdef
(apt-get output...)
---> 8e7d6c5b4a3f
Removing intermediate container 123456abcdef
Step 4/4 : CMD ["echo", "My custom image built successfully!"]
---> Running in fedcba987654
---> 9a8b7c6d5e4f
Removing intermediate container fedcba987654
Successfully built 9a8b7c6d5e4f
Successfully tagged myimage:0.1

After the build completes, you can verify the image exists using docker images:

docker images

You should see myimage with the tag 0.1 listed. You can now run containers from this custom image.

The build context is important. When you use instructions like COPY or ADD, Docker looks for the specified files within the context directory. Sending unnecessary files (like .git directories, build artifacts, local dependencies) can slow down the build and increase image size. Use a .dockerignore file (similar syntax to .gitignore) in the context directory root to exclude files and directories from being sent to the daemon.