mirror of
https://github.com/certbot/certbot.git
synced 2026-05-28 04:34:11 -04:00
leverage docker buildkit bake to speed up build times
This commit is contained in:
parent
accee97476
commit
c10192b6d8
4 changed files with 251 additions and 87 deletions
|
|
@ -6,46 +6,69 @@ set -euxo pipefail
|
|||
# filesystem
|
||||
|
||||
# Usage:
|
||||
# ./build.sh all
|
||||
# ./build.sh <architectures>
|
||||
# ./build.sh <tag> all
|
||||
# ./build.sh <tag> <architectures>
|
||||
# The <tag> argument is used to identify the code version (e.g v2.3.1) or type of build
|
||||
# (e.g. nightly). This will be used when saving images to the docker image cache.
|
||||
# The argument "all" will build all know architectures. Alternatively, the
|
||||
# user may provide a comma separated list of architectures drawn from the
|
||||
# known architectures. Know architectures include amd64, arm32v6, and arm64v8.
|
||||
|
||||
source "$(realpath $(dirname ${BASH_SOURCE[0]}))/lib/common"
|
||||
|
||||
REQUESTED_ARCH_LIST=$(InterpretArchRequest "$1")
|
||||
PLATFORM_SPEC=$(archList2platformList "${REQUESTED_ARCH_LIST[@]}")
|
||||
#used by docker buildx bake, so mark export
|
||||
export TAG_VER="$1"
|
||||
if [ -z "$TAG_VER" ]; then
|
||||
echo "We cannot tag Docker images with an empty string!" >&2
|
||||
exit 1
|
||||
fi
|
||||
ARCH_LIST="$2"
|
||||
if [ -z "$ARCH_LIST" ]; then
|
||||
echo "Architectures must be specified!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export REGISTRY_SPEC="${DOCKER_HUB_ORG}/"
|
||||
|
||||
#jump to root, matching popd handed by Cleanup on EXIT via trap
|
||||
pushd "${REPO_ROOT}"
|
||||
|
||||
# Set trap here, as the popd won't work as expected if invoked prior to pushd
|
||||
trap Cleanup EXIT
|
||||
|
||||
# Create the builder
|
||||
CreateBuilder
|
||||
|
||||
# Helper function to build certbot image
|
||||
BuildCertbot() {
|
||||
docker buildx build \
|
||||
$(StandardCertbotBuildArgs ${PLATFORM_SPEC}) \
|
||||
--cache-to=type=local,dest=${DOCKER_CACHE}/certbot \
|
||||
.
|
||||
BuildAll() {
|
||||
docker buildx bake -f ${WORK_DIR}/docker-bake.hcl \
|
||||
--builder certbot_builder \
|
||||
--set *.cache-to=type=local,dest=.docker_cache \
|
||||
build-all
|
||||
}
|
||||
# --progress plain
|
||||
BuildAndCacheByArch() {
|
||||
export TAG_ARCH=$1
|
||||
docker buildx bake -f ${WORK_DIR}/docker-bake.hcl \
|
||||
--builder certbot_builder \
|
||||
--set *.platform=$(arch2platform ${TAG_ARCH}) \
|
||||
--set *.cache-from=type=local,src=.docker_cache \
|
||||
build-all --load
|
||||
}
|
||||
|
||||
# Helper function to build plugin image
|
||||
BuildPlugin() {
|
||||
PLUGIN=$1
|
||||
docker buildx build \
|
||||
$(StandardPluginBuildArgs ${PLATFORM_SPEC} ${PLUGIN}) \
|
||||
--cache-to=type=local,dest=${DOCKER_CACHE}/${PLUGIN} \
|
||||
.
|
||||
}
|
||||
# If the request was for all, max out the buildkit parallelization logic
|
||||
if [ "$ARCH_LIST" = "all" ]; then
|
||||
BuildAll
|
||||
fi
|
||||
# split arch list into an array for per-arch saving of images to the docker image cache
|
||||
IFS_OLD="$IFS"
|
||||
IFS=","
|
||||
read -ra REQUESTED_ARCH_ARRAY <<< $(InterpretArchRequest "$ARCH_LIST")
|
||||
IFS="$IFS_OLD"
|
||||
for ARCH in "${REQUESTED_ARCH_ARRAY[@]}"; do
|
||||
# If the build was already done by BuildAll, then the existing image is pulled
|
||||
# from the build cache. Otherwise, it gets built on demand here.
|
||||
# Either way, images get tagged and loaded to the docker image cache
|
||||
# for use by test and deploy
|
||||
BuildAndCacheByArch $ARCH
|
||||
done
|
||||
|
||||
# Step 1: Certbot core Docker
|
||||
BuildCertbot
|
||||
|
||||
# Step 2: Certbot DNS plugins Docker images
|
||||
for PLUGIN in "${CERTBOT_PLUGINS[@]}"; do
|
||||
BuildPlugin $PLUGIN
|
||||
done
|
||||
|
|
|
|||
|
|
@ -41,32 +41,39 @@ LatestTag() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Helper function to deploy certbot image with version and optional latest tag
|
||||
DeployCertbot() {
|
||||
DOCKER_REPO="${DOCKER_HUB_ORG}/certbot"
|
||||
|
||||
docker buildx build \
|
||||
$(StandardCertbotBuildArgs ${PLATFORM_SPEC}) \
|
||||
-t ${DOCKER_REPO}:${TAG_BASE} $(LatestTag ${TAG_BASE}) \
|
||||
--push \
|
||||
.
|
||||
|
||||
REGISTRY_SPEC="${DOCKER_HUB_ORG}/"
|
||||
|
||||
DeployImage() {
|
||||
IMAGE_NAME=$1
|
||||
TAG_ARCH=$2
|
||||
TAG_VER=$3
|
||||
docker push "${REGISTRY_SPEC}${IMAGE_NAME}:${TAG_ARCH}-${TAG_VER}"
|
||||
if [[ "${TAG_BASE}" =~ ^v([2-9]|[1-9][0-9]+)\.[0-9]+\.[0-9]+$ ]]; then
|
||||
docker tag "${REGISTRY_SPEC}${IMAGE_NAME}:${TAG_ARCH}-${TAG_VER}" "${REGISTRY_SPEC}${IMAGE_NAME}:latest"
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper function to deploy plugin image with version and optional latest tag
|
||||
DeployPlugin() {
|
||||
PLUGIN=$1
|
||||
DOCKER_REPO="${DOCKER_HUB_ORG}/${PLUGIN}"
|
||||
docker buildx build \
|
||||
$(StandardPluginBuildArgs ${PLATFORM_SPEC} ${PLUGIN}) \
|
||||
-t ${DOCKER_REPO}:${TAG_BASE} $(LatestTag ${TAG_BASE}) \
|
||||
--push \
|
||||
.
|
||||
DeployManifest() {
|
||||
IMAGE_NAME=$1
|
||||
local IFS=","
|
||||
read -ra REQUESTED_ARCH_ARRAY <<< $(InterpretArchRequest "$2")
|
||||
TAG_VER=$3
|
||||
|
||||
SRC_IMAGES=""
|
||||
for TAG_ARCH in "${REQUESTED_ARCH_ARRAY[@]}"; do
|
||||
SRC_IMAGES+="${REGISTRY_SPEC}${IMAGE_NAME}:${TAG_ARCH}-${TAG_VER} "
|
||||
done
|
||||
|
||||
docker buildx imagetools create -t "${REGISTRY_SPEC}${IMAGE_NAME}:${TAG_VER} $SRC_IMAGES"
|
||||
}
|
||||
|
||||
# Step 1: Certbot core Docker
|
||||
DeployCertbot
|
||||
|
||||
# Step 2: Certbot DNS plugins Docker images
|
||||
for PLUGIN in "${CERTBOT_PLUGINS[@]}"; do
|
||||
DeployPlugin $PLUGIN
|
||||
for TAG_ARCH in "${REQUESTED_ARCH_ARRAY[@]}"; do
|
||||
DeployImage certbot $TAG_ARCH $TAG_VER
|
||||
for PLUGIN in "${CERTBOT_PLUGINS[@]}"; do
|
||||
DeployImage $PLUGIN $TAG_ARCH $TAG_VER
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
|
|
|
|||
146
tools/docker/docker-bake.hcl
Normal file
146
tools/docker/docker-bake.hcl
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
group "build-all" {
|
||||
targets = ["certbot",
|
||||
"dns-dnsmadeeasy",
|
||||
"dns-dnsimple",
|
||||
"dns-ovh",
|
||||
"dns-cloudflare",
|
||||
"dns-digitalocean",
|
||||
"dns-google",
|
||||
"dns-luadns",
|
||||
"dns-nsone",
|
||||
"dns-rfc2136",
|
||||
"dns-route53",
|
||||
"dns-gehirn",
|
||||
"dns-linode",
|
||||
"dns-sakuracloud"]
|
||||
|
||||
}
|
||||
|
||||
variable "WORK_DIR" {
|
||||
default = "tools/docker"
|
||||
}
|
||||
|
||||
variable "TAG_VER" {
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "TAG_ARCH" {
|
||||
default = "auto"
|
||||
}
|
||||
|
||||
variable "REGISTRY_SPEC" {
|
||||
// if provided, this should include the trailing slash (e.g. "certbot/)
|
||||
default = ""
|
||||
}
|
||||
|
||||
target "certbot" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot"
|
||||
tags = ["${REGISTRY_SPEC}certbot:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-dnsmadeeasy" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-dnsmadeeasy"}
|
||||
tags = ["${REGISTRY_SPEC}dns-dnsmadeeasy:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-dnsimple" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-dnsimple"}
|
||||
tags = ["${REGISTRY_SPEC}dns-dnsimple:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-ovh" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-ovh"}
|
||||
tags = ["${REGISTRY_SPEC}dns-ovh:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-cloudflare" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-cloudflare"}
|
||||
tags = ["${REGISTRY_SPEC}dns-cloudflare:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-digitalocean" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-digitalocean"}
|
||||
tags = ["${REGISTRY_SPEC}dns-digitalocean:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-google" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-google"}
|
||||
tags = ["${REGISTRY_SPEC}dns-google:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-luadns" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-luadns"}
|
||||
tags = ["${REGISTRY_SPEC}dns-luadns:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-nsone" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-nsone"}
|
||||
tags = ["${REGISTRY_SPEC}dns-nsone:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-rfc2136" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-rfc2136"}
|
||||
tags = ["${REGISTRY_SPEC}dns-rfc2136:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-route53" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-route53"}
|
||||
tags = ["${REGISTRY_SPEC}dns-route53:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-gehirn" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-gehirn"}
|
||||
tags = ["${REGISTRY_SPEC}dns-gehirn:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-linode" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-linode"}
|
||||
tags = ["${REGISTRY_SPEC}dns-linode:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
target "dns-sakuracloud" {
|
||||
dockerfile = "${WORK_DIR}/Dockerfile"
|
||||
target = "certbot-plugin"
|
||||
contexts = {plugin-src = "certbot-dns-sakuracloud"}
|
||||
tags = ["${REGISTRY_SPEC}dns-sakuracloud:${TAG_ARCH}-${TAG_VER}"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8", "linux/arm/v6"]
|
||||
}
|
||||
|
||||
|
|
@ -4,15 +4,30 @@ set -euxo pipefail
|
|||
# This script tests certbot docker and certbot dns plugin images.
|
||||
|
||||
# Usage:
|
||||
# ./test.sh all
|
||||
# ./test.sh <architectures>
|
||||
# ./test.sh <tag> all
|
||||
# ./test.sh <tag> <architectures>
|
||||
# The <tag> argument is used to identify the code version (e.g v2.3.1) or type of build
|
||||
# (e.g. nightly). This will be used when saving images to the docker image cache.
|
||||
# The argument "all" will build all know architectures. Alternatively, the
|
||||
# user may provide a comma separated list of architectures drawn from the
|
||||
# known architectures. Know architectures include amd64, arm32v6, and arm64v8.
|
||||
|
||||
source "$(realpath $(dirname ${BASH_SOURCE[0]}))/lib/common"
|
||||
|
||||
REQUESTED_ARCH_LIST=$(InterpretArchRequest "$1")
|
||||
TAG_VER="$1"
|
||||
if [ -z "$TAG_VER" ]; then
|
||||
echo "We cannot tag Docker images with an empty string!" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$2" ]; then
|
||||
echo "Architectures must be specified!" >&2
|
||||
exit 1
|
||||
fi
|
||||
IFS_OLD="$IFS"
|
||||
IFS=","
|
||||
read -ra REQUESTED_ARCH_ARRAY <<< $(InterpretArchRequest "$2")
|
||||
IFS="$IFS_OLD"
|
||||
|
||||
|
||||
#jump to root, matching popd handed by Cleanup on EXIT via trap
|
||||
pushd "${REPO_ROOT}"
|
||||
|
|
@ -23,46 +38,19 @@ trap Cleanup EXIT
|
|||
CreateBuilder
|
||||
|
||||
|
||||
IFS_OLD="$IFS"
|
||||
IFS=","
|
||||
read -ra REQUESTED_ARCH_ARRAY <<< "$REQUESTED_ARCH_LIST"
|
||||
IFS="$IFS_OLD"
|
||||
REGISTRY_SPEC="${DOCKER_HUB_ORG}/"
|
||||
|
||||
# Helper function to load and test certbot image
|
||||
TestCertbot() {
|
||||
ARCH=$1
|
||||
DOCKER_REPO="${DOCKER_HUB_ORG}/certbot"
|
||||
docker buildx build \
|
||||
$(StandardCertbotBuildArgs $(arch2platform ${ARCH})) \
|
||||
-t ${DOCKER_REPO}:${ARCH} \
|
||||
--load \
|
||||
.
|
||||
docker run --rm "${DOCKER_REPO}:${ARCH}" plugins --prepare
|
||||
docker rmi ${DOCKER_REPO}:${ARCH}
|
||||
TestImage() {
|
||||
IMAGE_NAME=$1
|
||||
TAG_ARCH=$2
|
||||
TAG_VER=$3
|
||||
docker run --rm "${REGISTRY_SPEC}${IMAGE_NAME}:${TAG_ARCH}-${TAG_VER}" plugins --prepare
|
||||
}
|
||||
|
||||
# Helper function to load and test plugin image
|
||||
TestPlugin() {
|
||||
ARCH=$1
|
||||
PLUGIN=$2
|
||||
DOCKER_REPO="${DOCKER_HUB_ORG}/${PLUGIN}"
|
||||
docker buildx build \
|
||||
$(StandardPluginBuildArgs $(arch2platform ${ARCH}) ${PLUGIN}) \
|
||||
-t ${DOCKER_REPO}:${ARCH} \
|
||||
--load \
|
||||
.
|
||||
docker run --rm "${DOCKER_REPO}:${ARCH}" plugins --prepare
|
||||
docker rmi ${DOCKER_REPO}:${ARCH}
|
||||
}
|
||||
|
||||
# Step 1: Certbot core Docker
|
||||
for ARCH in "${REQUESTED_ARCH_ARRAY[@]}"; do
|
||||
TestCertbot $ARCH
|
||||
done
|
||||
|
||||
# Step 2: Certbot DNS plugins Docker images
|
||||
for ARCH in "${REQUESTED_ARCH_ARRAY[@]}"; do
|
||||
for TAG_ARCH in "${REQUESTED_ARCH_ARRAY[@]}"; do
|
||||
TestImage certbot $TAG_ARCH $TAG_VER
|
||||
for PLUGIN in "${CERTBOT_PLUGINS[@]}"; do
|
||||
TestPlugin $ARCH $PLUGIN
|
||||
TestImage $PLUGIN $TAG_ARCH $TAG_VER
|
||||
done
|
||||
done
|
||||
|
|
|
|||
Loading…
Reference in a new issue