Docker Buildx is a tool that allows you to build multi-architecture Docker images using a single command. This is particularly useful if you need to support multiple platforms or architectures, such as x86 and ARM, or if you want to optimize your images for specific hardware.
In this tutorial, we will show you how to use Docker Buildx to build multi-architecture Docker images and how to use secrets and environment variables in your build process.
To get started, make sure you have Docker and Docker Buildx installed on your system. You can check if Docker Buildx is installed by running the following command:
docker buildx version
If Docker Buildx is not installed, you can install it by running the following command:
docker buildx install
Once you have Docker Buildx installed, you can use it to build multi-architecture Docker images using a shell script. Here’s an example build.sh script:
#!/bin/bash
DOCKERFILE="Dockerfile-D"
IMAGE="spaklci"
VERSION="v1.0.0"
CONTAINER_REGISTRY="registry.gitlab.com"
REG_USERNAME="username"
REG_TOKEN="token"
# echo ${REG_TOKEN} | docker login ${CONTAINER_REGISTRY} -u ${REG_USERNAME} --password-stdin
echo "dGhpcyBpcyBhIHN1cGVyIHNlY3JldCB0b2tlbg==" > ./top_secret
export SUPER_SECRET="U0VDUkVUTUVTU0FHRQ=="
sudo docker pull moby/buildkit:buildx-stable-1
BUILDER_NAME="mybuilder"
if sudo docker buildx inspect $BUILDER_NAME > /dev/null 2>&1; then
sudo docker buildx rm $BUILDER_NAME
fi
sudo docker buildx ls
sudo docker buildx create --name $BUILDER_NAME --driver docker-container --bootstrap --use
sudo docker buildx use $BUILDER_NAME
sudo docker buildx inspect --bootstrap
DOCKER_BUILDKIT=1 sudo docker buildx build \
--no-cache \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
--build-arg traefik_version=${TRAEFIK_VERSION} \
--file ${DOCKERFILE} \
-t $IMAGE:$VERSION \
-t $IMAGE:latest \
--push \
.
docker manifest inspect $IMAGE:$VERSION
rm ./top_secret
unset SUPER_SECRET
In this script,
- the docker login command is used to authenticate with the container registry, and the top_secret file is created to demonstrate how to use a secret in the build process.
- The docker pull command is used to pull the latest version of the moby/buildkit:buildx-stable-1 image, which is required for Docker Buildx.
- The docker context create and docker buildx create commands are used to set up the Docker Buildx builder context.
- Finally, the DOCKER_BUILDKIT=1 docker buildx build command is used to build the Docker image using the linux/amd64 and linux/arm64 platforms and the secrets specified in the command.
Here’s an example Dockerfile that uses the secrets specified in the build.sh script:
FROM alpine:latest
RUN --mount=type=secret,id=SECRET_1,dst=/run/secrets/secret_1 \
--mount=type=secret,id=SECRET_2,dst=/run/secrets/secret_2 \
echo "Secret 1: $(cat /run/secrets/secret_1 | base64 -d)" >> /secrets \
&& echo "Secret 2: $(cat /run/secrets/secret_2 | base64 -d)" >> /secrets
In this Dockerfile, the –mount flag is used to mount the secrets specified in the build.sh script. The cat and base64 -d commands are used to decode the secrets and print them to the console.
/ # cat secrets
Secret 1: this is a super secret token
Secret 2: SECRETMESSAGE
Gitlab Pipeline #
variables:
BUILD_IMAGE: docker
DIND_IMAGE: docker:dind
NO_PROXY: "docker"
IMAGE: "image-name"
VERSION: "v1.0.0"
default:
tags:
- default
.docker-login: &docker-login
- echo $CI_JOB_TOKEN | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
.docker-logout: &docker-logout
- docker logout $CI_REGISTRY
multi_arch_build:
stage: build
image: $BUILD_IMAGE
services:
- name: $DIND_IMAGE
alias: docker
before_script:
- *docker-login
after_script:
- *docker-logout
script:
# Setup multi-platform build
- docker pull moby/buildkit:buildx-stable-1
- docker context create builder-context
- docker buildx create builder-context --name mybuilder --driver docker-container --bootstrap --use
# Build multi-arch containers
- >
DOCKER_BUILDKIT=1 docker buildx build \
--no-cache \
--push \
--platform linux/amd64,linux/arm64 \
--secret id=SECRET_1,src=./top_secret \
--secret id=SECRET_2,env=SUPER_SECRET \
--file ${DOCKERFILE} \
--tag $IMAGE:$VERSION \
--tag $IMAGE:latest .