Optimize Your Docker Builds with Dockerfile v1.7.0 Innovations
Docker continues to innovate, making containerization more efficient and accessible. The release of Dockerfile version 1.7.0 introduces a suite of powerful features that enhance the way we build Docker images. Whether you’re new to Docker or a seasoned pro, these updates are designed to streamline your workflow and optimize your builds.
In this article, we’ll delve into all the new capabilities introduced in Dockerfile v1.7.0 and the experimental v1.7-labs
, complete with examples and explanations to help you get the most out of these enhancements.
1. Heredoc Support for Multi-line Commands
Simplifying Multi-line Scripts
Dockerfile v1.7.0 introduces heredoc syntax, allowing you to write multi-line commands more cleanly. This feature improves readability and maintainability, especially when dealing with complex scripts.
Example:
# syntax=docker/dockerfile:1.7.0
FROM alpine
RUN <<EOF
echo "Starting setup..."
apk update
apk add --no-cache python3 py3-pip
pip3 install --no-cache-dir flask
EOF
Explanation:
- The
<<EOF
indicates the start of a heredoc block. - You can write multiple lines of commands without chaining them with
&&
. - The heredoc ends when
EOF
is encountered.
2. Conditional Builds with Build Expressions
Making Builds More Dynamic
Conditional builds allow you to include or exclude parts of your Dockerfile based on build-time variables, making your builds more flexible.
Example:
# syntax=docker/dockerfile:1.7.0
FROM node:14
ARG INSTALL_TOOLS=false
RUN <<EOF
{% if $INSTALL_TOOLS == 'true' %}
apt-get update && apt-get install -y vim
{% endif %}
EOF
Explanation:
- The
ARG
instruction defines a build-time variableINSTALL_TOOLS
. - The heredoc uses a simple conditional syntax.
- You can control whether to install additional tools by setting
INSTALL_TOOLS
when building.
Building with Conditional Argument:
docker build --build-arg INSTALL_TOOLS=true -t my-node-app .
3. Improved RUN --mount
Syntax
Enhanced Build-Time Mounts
The RUN --mount
flag has been improved to provide more flexibility with build-time mounts, such as caching and binding directories.
Example: Caching Package Downloads
# syntax=docker/dockerfile:1.7.0
FROM ubuntu:20.04
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && apt-get install -y build-essential
Explanation:
type=cache
creates a persistent cache mount at/var/cache/apt
.- Speeds up subsequent builds by caching package downloads.
Example: Binding a Directory
# syntax=docker/dockerfile:1.7.0
FROM python:3.9
RUN --mount=type=bind,source=./local_requirements.txt,target=/requirements.txt \
pip install -r /requirements.txt
Explanation:
type=bind
mounts a local file or directory into the build.- Useful for including files at build-time without adding them to the image.
4. Mount Options in COPY
and ADD
More Control Over File Operations
You can now use mount options directly with COPY
and ADD
, providing greater control over how files are handled during the build.
Example: Copying with Cache Mount
# syntax=docker/dockerfile:1.7.0
FROM golang:1.17
COPY --mount=type=cache,target=/go/pkg/mod \
. /app
WORKDIR /app
RUN go build -o myapp .
Explanation:
- The
--mount
flag withCOPY
allows caching Go modules. - Reduces build times by avoiding re-downloading dependencies.
5. Enhanced Secrets Handling
Securely Managing Sensitive Data
Dockerfile v1.7.0 improves the handling of secrets during the build process, ensuring sensitive information doesn’t end up in the final image.
Example: Using Secret Files
# syntax=docker/dockerfile:1.7.0
FROM alpine
RUN --mount=type=secret,id=mysecret,dst=/run/secrets/mysecret \
cat /run/secrets/mysecret > /root/secret_info
Explanation:
type=secret
mounts a secret into the build at the specified destination.- Secrets are not stored in the image layers.
Passing Secrets During Build:
docker build --secret id=mysecret,src=mysecret.txt -t my-secure-app .
6. Variable Expansions
Dynamic Value Substitutions
With Dockerfile v1.7-labs
, you can perform variable expansions within your Dockerfile, allowing for more dynamic and flexible builds.
Example: Using Variable Expansions
# syntax=docker/dockerfile:1.7-labs
FROM alpine
ARG VERSION=1.0.0
ENV APP_DIR=/opt/myapp-$VERSION
RUN mkdir -p $APP_DIR
Explanation:
- Variables like
$VERSION
and$APP_DIR
are expanded in theRUN
andENV
instructions. - Allows you to use build-time arguments and environment variables seamlessly.
Building with Custom Version:
docker build --build-arg VERSION=2.0.0 -t myapp:2.0.0 .
7. Copy with Keeping Parent Directories
Preserving Directory Structure
Dockerfile v1.7-labs
introduces the ability to copy files while keeping their parent directories, which is useful for maintaining the original directory hierarchy.
Example: Copying with Parent Directories
# syntax=docker/dockerfile:1.7-labs
FROM alpine
COPY --keep-parent dir1/dir2/file.txt /destination/
Explanation:
- The
--keep-parent
flag tells Docker to preserve the parent directories. - The file structure
dir1/dir2/file.txt
will be replicated under/destination/
.
Resulting Directory Structure:
/destination/dir1/dir2/file.txt
8. Exclusion Filters
Fine-Grained Control Over File Copying
Exclusion filters allow you to exclude specific files or patterns when using COPY
or ADD
, giving you greater control over what gets included in your image.
Example: Using Exclusion Filters
# syntax=docker/dockerfile:1.7-labs
FROM node:14
COPY . /app/ \
--exclude=*.test.js \
--exclude=docs/
WORKDIR /app
RUN npm install
Explanation:
- The
--exclude
flag specifies patterns to exclude during the copy. - In this example, all
.test.js
files and thedocs/
directory are excluded. - Helps reduce image size by omitting unnecessary files.
9. Contexts from Archives and URLs
Flexibility in Build Context Sources
You can now specify build contexts from tar archives or URLs, making it easier to build images from different sources.
Example: Using a Tar Archive as Context
docker build -f Dockerfile https://example.com/myapp.tar.gz -t myapp:latest
Explanation:
- The build context is provided as a URL pointing to a tar archive.
- Docker fetches and uses the archive as the build context.
10. Platform-Specific FROM
Instructions
Building Multi-Platform Images
The FROM
instruction now supports specifying the target platform, enabling multi-platform builds within a single Dockerfile.
Example: Multi-Platform Base Images
# syntax=docker/dockerfile:1.7.0
FROM --platform=$BUILDPLATFORM golang:1.17 AS builder
WORKDIR /app
COPY . .
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o myapp .
FROM alpine
COPY --from=builder /app/myapp /usr/local/bin/myapp
Explanation:
$BUILDPLATFORM
and$TARGETPLATFORM
are automatic variables.- Allows building binaries for different architectures.
11. Build-Time Arguments in FROM
Dynamic Base Images
You can now use build-time arguments in the FROM
instruction to dynamically select the base image.
Example: Using Arguments in FROM
# syntax=docker/dockerfile:1.7.0
ARG BASE_IMAGE=python:3.9-slim
FROM ${BASE_IMAGE}
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
Explanation:
ARG
beforeFROM
defines a variable usable inFROM
.- You can change the base image during the build.
Building with a Different Base Image:
docker build --build-arg BASE_IMAGE=python:3.8-slim -t my-python-app .
12. Support for Multiple Build Contexts
Leveraging Additional Contexts
Dockerfile v1.7.0 allows you to specify additional build contexts, making it easier to include files from different locations.
Example: Using Multiple Contexts
# syntax=docker/dockerfile:1.7.0
FROM ubuntu:20.04
COPY --from=assets /images /usr/share/app/images
Building with Multiple Contexts:
docker build \
--build-context assets=./path/to/assets \
-t my-multi-context-app .
Explanation:
--build-context
specifies additional contexts with a name.--from=assets
refers to the context namedassets
.
13. Getting Started with Dockerfile v1.7.0 and v1.7-labs
To take advantage of these new features, ensure you’re using the latest Docker version and specify the Dockerfile syntax version.
For Stable Features:
# syntax=docker/dockerfile:1.7.0
For Experimental Features (v1.7-labs
):
# syntax=docker/dockerfile:1.7-labs
Note: The v1.7-labs
syntax includes experimental features like variable expansions, parent directory preservation in COPY
, and exclusion filters.
Enable BuildKit, Docker’s advanced build engine:
export DOCKER_BUILDKIT=1
Alternatively, use the Docker build command with BuildKit enabled:
docker buildx build -t my-app .
Conclusion
Dockerfile v1.7.0 and the experimental v1.7-labs
bring significant improvements to the Docker build process. From heredoc support and conditional builds to variable expansions and exclusion filters, these features empower you to create more efficient and secure Docker images.
By incorporating these capabilities into your workflow, you can streamline development, optimize builds, and maintain greater control over your containerized applications.
Further Reading
- Best Practices for Writing Dockerfiles
- New Dockerfile Capabilities in v1.7.0
- Dockerfile Reference
- Docker BuildKit Documentation
- Dockerfile Experimental Features (
v1.7-labs
)
Like to learn more?
Find more in-depth guides on my website.
Follow me on Twitter for updates in AI, DevOps, and tech.
Connect on LinkedIn to chat or collaborate!