Skip to main content
  1. Posts/

Multi Arch Docker build with Buildx

·552 words·3 mins· loading · loading · ·
DevOps Containers Docker Buildx Multi-Architecture Secrets Environment Variables
Brock Henrie
Author
Brock Henrie
A little bit about me
Table of Contents

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 .