1. Introduction
Docker is a popular deployment tool that enables us to package and run apps. Due to the high adoption, there has been a need to extend functionality based on different requirements. Thus to achieve this, third parties make use of docker plugins.
For example, if we want data to persist data across different hosts, we use a volumes plugin. Another commonly used plugin is Docker buildx. It extends the building ability of images by using the BuildKit builder. Hence, with the plugin, we can build images for different platforms and architectures. Furthermore, it supports parallel multi-stage makes with custom contexts.
In this tutorial, we’ll look at an introduction to Docker buildx.
2. Installing buildx
First and foremost, for buildx to run, we need to have Docker installed. Docker buildx support is available from Docker engine 19.00 onwards.
Let’s first start by checking our Docker version:
$ docker --version
Docker version 19.03.8, build afacb8b
Next, we enable the Docker experimental feature by setting the environment variable:
$ export DOCKER_CLI_EXPERIMENTAL=enabled
To ensure our setting remains after the session, We add the variable to $HOME/.bashrc for Bash. With that in place, we should now have access to buildx:
$ docker buildx
Usage: docker buildx COMMAND
Build with BuildKit
Management Commands:
imagetools Commands to work on images in registry
Commands:
bake Build from a file
build Start a build
create Create a new builder instance
inspect Inspect current builder instance
ls List builder instances
rm Remove a builder instance
stop Stop builder instance
use Set the current builder instance
version Show buildx version information
Run 'docker buildx COMMAND --help' for more information on a command.
This shows common commands and the syntax for each command.
3. Building with buildx
buildx performs all the Docker build capabilities. Therefore, we can run all comfortably and execute them. For instance, specifying the target platform, build caching, and output configs. Over and beyond that, buildx provides extra features.
Firstly the ability to build images for multiple platforms simultaneously. Secondly, multi-stage builds within a single dockerfile for smaller images. Finally, the ability to customize inputs, arguments, or variables during the build process.
Let’s dive into an example by creating an instance:
$ docker buildx create --name ourbuilder
ourbuilder
This creates a build instance called ourbuilder.
Next, we’ll set it as the active directory:
$ docker buildx use ourbuilder
Next, let’s create a dockerfile to run a simple node application:
# Base image
FROM node:14-alpine
# Set working directory
WORKDIR /app
# Copy application files
COPY . .
# Install dependencies
RUN npm install --production
# Expose the port
EXPOSE 3000
# Start the application
CMD ["node", "app.js"]
Here we are using node.js base image and setting the working directory to /app. Then we copy app files into the container. Then we install all dependencies, expose port 3000 and start the app:
$ docker buildx build --platform linux/amd64,linux/arm64 -t ourapp:latest .
time="2023-06-01T07:13:20+03:00" level=warning msg="No output specified for docker-container driver.
Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load"
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 73.2s done
#1 creating container buildx_buildkit_ourbuilder0
#1 creating container buildx_buildkit_ourbuilder0 2.1s done
#1 DONE 75.4s
#3 [internal] load .dockerignore
#3 transferring context: 0.0s
#3 transferring context: 2B 0.1s done
#3 DONE 0.3s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 294B 0.0s done
#2 DONE 0.4s
#4 [linux/amd64 internal] load metadata for docker.io/library/node:14-alpin...
#4 DONE 4.7s
.... truncated .....
We specify the target platforms using the –platform flag. We’re targeting the x86 (Linux/amd64) and ARM (Linux/arm64) architectures in this case. We also provide the tag -t ourapp:latest to tag the built image with the name ourapp and the latest tag. The . specifies the build context, which is the current directory.
Docker buildx auto handles the multi-platform build and generates separate images for each targeted architecture.
4. Conclusion
In this tutorial, we have explored Docker buildx, a tool that extends the building and managing abilities of Docker images. It simplifies the process by supporting parallelized builds, custom-build contexts, and multi-stage builds.