mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 19:02:52 +02:00
Docker build improvements (#8218)
Fixes https://github.com/certbot/certbot/issues/8208. Fixes https://github.com/certbot/certbot/issues/8198. In addition to those two linked issues, this PR: * Splits both the build and deploy steps based on architecture for performance. The Docker builds should no longer be the bottleneck in any stage of the pipeline. * Skips building Docker images for ARM on `test-` branches like [we do for snaps](https://github.com/certbot/certbot/blob/e8a232297d6faedb3b0bffc197a2e98c2e59edcb/.azure-pipelines/templates/jobs/packaging-jobs.yml#L67-L71). I initially didn't want to do this, but the ARM builds take ~18 minutes which is significantly longer than any other job currently running on our `test-` branches. You can see tests running on my fork at: * [Release pipeline](https://dev.azure.com/bmw0523/bmw/_build/results?buildId=387&view=results) * [Test pipeline](https://dev.azure.com/bmw0523/bmw/_build/results?buildId=388&view=results) * [Nightly pipeline](https://dev.azure.com/bmw0523/bmw/_build/results?buildId=390&view=results) * update script intro * update readme * ParseRequestedArch * build all arch in Azure * Build docker images during testing/packaging. * require global variable? * Error if TAG_BASE is empty. * prepare build job * change variable syntax * Update deploy stage. * remove old dockerTag param * add displayName * fix docker images command * split docker_build by arch * Allow deploying a subset of architectures. * deploy in parallel * Skip ARM builds on test- branches. * fix spacing
This commit is contained in:
@@ -5,5 +5,10 @@ trigger:
|
|||||||
- test-*
|
- test-*
|
||||||
pr: none
|
pr: none
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# We don't publish our Docker images in this pipeline, but when building them
|
||||||
|
# for testing, let's use the nightly tag.
|
||||||
|
dockerTag: nightly
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- template: templates/stages/test-and-package-stage.yml
|
- template: templates/stages/test-and-package-stage.yml
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ schedules:
|
|||||||
- master
|
- master
|
||||||
always: true
|
always: true
|
||||||
|
|
||||||
|
variables:
|
||||||
|
dockerTag: nightly
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- template: templates/stages/test-and-package-stage.yml
|
- template: templates/stages/test-and-package-stage.yml
|
||||||
- template: templates/stages/deploy-stage.yml
|
- template: templates/stages/deploy-stage.yml
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ trigger:
|
|||||||
- v*
|
- v*
|
||||||
pr: none
|
pr: none
|
||||||
|
|
||||||
|
variables:
|
||||||
|
dockerTag: ${{variables['Build.SourceBranchName']}}
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- template: templates/stages/test-and-package-stage.yml
|
- template: templates/stages/test-and-package-stage.yml
|
||||||
- template: templates/stages/changelog-stage.yml
|
- template: templates/stages/changelog-stage.yml
|
||||||
- template: templates/stages/deploy-stage.yml
|
- template: templates/stages/deploy-stage.yml
|
||||||
parameters:
|
parameters:
|
||||||
snapReleaseChannel: beta
|
snapReleaseChannel: beta
|
||||||
dockerTag: ${{variables['Build.SourceBranchName']}}
|
|
||||||
- template: templates/stages/notify-failure-stage.yml
|
- template: templates/stages/notify-failure-stage.yml
|
||||||
|
|||||||
@@ -1,4 +1,35 @@
|
|||||||
jobs:
|
jobs:
|
||||||
|
- job: docker_build
|
||||||
|
pool:
|
||||||
|
vmImage: ubuntu-18.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
amd64:
|
||||||
|
DOCKER_ARCH: amd64
|
||||||
|
# Do not run the heavy non-amd64 builds for test branches
|
||||||
|
${{ if not(startsWith(variables['Build.SourceBranchName'], 'test-')) }}:
|
||||||
|
arm32v6:
|
||||||
|
DOCKER_ARCH: arm32v6
|
||||||
|
arm64v8:
|
||||||
|
DOCKER_ARCH: arm64v8
|
||||||
|
steps:
|
||||||
|
- bash: tools/docker/build.sh $(dockerTag) $DOCKER_ARCH
|
||||||
|
displayName: Build the Docker images
|
||||||
|
# We don't filter for the Docker Hub organization to continue to allow
|
||||||
|
# easy testing of these scripts on forks.
|
||||||
|
- bash: |
|
||||||
|
DOCKER_IMAGES=$(docker images --filter reference='*/certbot' --filter reference='*/dns-*' --format '{{.Repository}}')
|
||||||
|
docker save --output images.tar $DOCKER_IMAGES
|
||||||
|
displayName: Save the Docker images
|
||||||
|
# If the name of the tar file or artifact changes, the deploy stage will
|
||||||
|
# also need to be updated.
|
||||||
|
- bash: mv images.tar $(Build.ArtifactStagingDirectory)
|
||||||
|
displayName: Prepare Docker artifact
|
||||||
|
- task: PublishPipelineArtifact@1
|
||||||
|
inputs:
|
||||||
|
path: $(Build.ArtifactStagingDirectory)
|
||||||
|
artifact: docker_$(DOCKER_ARCH)
|
||||||
|
displayName: Store Docker artifact
|
||||||
- job: installer_build
|
- job: installer_build
|
||||||
pool:
|
pool:
|
||||||
vmImage: vs2017-win2016
|
vmImage: vs2017-win2016
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ parameters:
|
|||||||
values:
|
values:
|
||||||
- edge
|
- edge
|
||||||
- beta
|
- beta
|
||||||
- name: dockerTag
|
|
||||||
type: string
|
|
||||||
default: nightly
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- stage: Deploy
|
- stage: Deploy
|
||||||
@@ -65,7 +62,22 @@ stages:
|
|||||||
- job: publish_docker
|
- job: publish_docker
|
||||||
pool:
|
pool:
|
||||||
vmImage: ubuntu-18.04
|
vmImage: ubuntu-18.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
amd64:
|
||||||
|
DOCKER_ARCH: amd64
|
||||||
|
arm32v6:
|
||||||
|
DOCKER_ARCH: arm32v6
|
||||||
|
arm64v8:
|
||||||
|
DOCKER_ARCH: arm64v8
|
||||||
steps:
|
steps:
|
||||||
|
- task: DownloadPipelineArtifact@2
|
||||||
|
inputs:
|
||||||
|
artifact: docker_$(DOCKER_ARCH)
|
||||||
|
path: $(Build.SourcesDirectory)
|
||||||
|
displayName: Retrieve Docker images
|
||||||
|
- bash: docker load --input $(Build.SourcesDirectory)/images.tar
|
||||||
|
displayName: Load Docker images
|
||||||
- task: Docker@2
|
- task: Docker@2
|
||||||
inputs:
|
inputs:
|
||||||
command: login
|
command: login
|
||||||
@@ -81,7 +93,5 @@ stages:
|
|||||||
# Certbot organization on Docker Hub.
|
# Certbot organization on Docker Hub.
|
||||||
containerRegistry: docker-hub
|
containerRegistry: docker-hub
|
||||||
displayName: Login to Docker Hub
|
displayName: Login to Docker Hub
|
||||||
- bash: tools/docker/build.sh ${{ parameters.dockerTag }}
|
- bash: tools/docker/deploy.sh $(dockerTag) $DOCKER_ARCH
|
||||||
displayName: Build the Docker images
|
|
||||||
- bash: tools/docker/deploy.sh ${{ parameters.dockerTag }}
|
|
||||||
displayName: Deploy the Docker images
|
displayName: Deploy the Docker images
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ DNS plugin Docker images to Docker Hub.
|
|||||||
High-level behavior
|
High-level behavior
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Running `./build.sh <TAG> && ./deploy.sh <TAG>` causes the Docker images to be
|
Running `./build.sh <TAG> all && ./deploy.sh <TAG> all` causes the Docker
|
||||||
built and deployed to Docker Hub where `<TAG>` is the base of the tag that
|
images to be built and deployed to Docker Hub for all supported architectures
|
||||||
should be given to the given images. The tag should either be `nightly` or a
|
where `<TAG>` is the base of the tag that should be given to the given images.
|
||||||
git version tag like `v0.34.0`. The given tag is only the base of the tag
|
The tag should either be `nightly` or a git version tag like `v0.34.0`. The
|
||||||
because the CPU architecture is also added to the tag.
|
given tag is only the base of the tag because the CPU architecture is also
|
||||||
|
added to the tag.
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
+13
-7
@@ -5,11 +5,12 @@ IFS=$'\n\t'
|
|||||||
# This script builds certbot docker and certbot dns plugins docker using the
|
# This script builds certbot docker and certbot dns plugins docker using the
|
||||||
# local Certbot files.
|
# local Certbot files.
|
||||||
|
|
||||||
# Usage: ./build.sh [TAG]
|
# Usage: ./build.sh [TAG] [all|amd64|arm32v6|arm64v8]
|
||||||
# with [TAG] corresponding the base of the tag to give the Docker images.
|
# with the [TAG] value corresponding the base of the tag to give the Docker
|
||||||
# Values should be something like `v0.34.0` or `nightly`. The given value is
|
# images and the 2nd value being the architecture to build snaps for.
|
||||||
# only the base of the tag because the things like the CPU architecture are
|
# Values for the tag should be something like `v0.34.0` or `nightly`. The
|
||||||
# also added to the full tag.
|
# given value is only the base of the tag because the things like the CPU
|
||||||
|
# architecture are also added to the full tag.
|
||||||
|
|
||||||
# As of writing this, runs of this script consistently fail in Azure
|
# As of writing this, runs of this script consistently fail in Azure
|
||||||
# Pipelines, but they are fixed by using Docker BuildKit. A log of the failures
|
# Pipelines, but they are fixed by using Docker BuildKit. A log of the failures
|
||||||
@@ -76,13 +77,18 @@ DownloadQemuStatic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TAG_BASE="$1"
|
TAG_BASE="$1"
|
||||||
|
if [ -z "$TAG_BASE" ]; then
|
||||||
|
echo "We cannot tag Docker images with an empty string!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ParseRequestedArch "${2}"
|
||||||
|
|
||||||
# Register QEMU handlers
|
# Register QEMU handlers
|
||||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
|
|
||||||
# Step 1: Certbot core Docker
|
# Step 1: Certbot core Docker
|
||||||
DOCKER_REPO="${DOCKER_HUB_ORG}/certbot"
|
DOCKER_REPO="${DOCKER_HUB_ORG}/certbot"
|
||||||
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
|
for TARGET_ARCH in "${ALL_REQUESTED_ARCH[@]}"; do
|
||||||
pushd "${REPO_ROOT}"
|
pushd "${REPO_ROOT}"
|
||||||
DownloadQemuStatic "${TARGET_ARCH}"
|
DownloadQemuStatic "${TARGET_ARCH}"
|
||||||
QEMU_ARCH=$(GetQemuArch "${TARGET_ARCH}")
|
QEMU_ARCH=$(GetQemuArch "${TARGET_ARCH}")
|
||||||
@@ -101,7 +107,7 @@ for plugin in "${CERTBOT_PLUGINS[@]}"; do
|
|||||||
pushd "${REPO_ROOT}/certbot-${plugin}"
|
pushd "${REPO_ROOT}/certbot-${plugin}"
|
||||||
# Copy QEMU static binaries downloaded when building the core Certbot image
|
# Copy QEMU static binaries downloaded when building the core Certbot image
|
||||||
cp ../qemu-*-static .
|
cp ../qemu-*-static .
|
||||||
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
|
for TARGET_ARCH in "${ALL_REQUESTED_ARCH[@]}"; do
|
||||||
QEMU_ARCH=$(GetQemuArch "${TARGET_ARCH}")
|
QEMU_ARCH=$(GetQemuArch "${TARGET_ARCH}")
|
||||||
BASE_IMAGE="${DOCKER_HUB_ORG}/certbot:${TARGET_ARCH}-${TAG_BASE}"
|
BASE_IMAGE="${DOCKER_HUB_ORG}/certbot:${TARGET_ARCH}-${TAG_BASE}"
|
||||||
docker build \
|
docker build \
|
||||||
|
|||||||
+19
-11
@@ -4,8 +4,9 @@ IFS=$'\n\t'
|
|||||||
|
|
||||||
# This script deploys new versions of Certbot and Certbot plugin docker images.
|
# This script deploys new versions of Certbot and Certbot plugin docker images.
|
||||||
|
|
||||||
# Usage: ./deploy.sh [TAG]
|
# Usage: ./deploy.sh [TAG] [all|amd64|arm32v6|arm64v8]
|
||||||
# with [TAG] corresponding the base of the tag to give the Docker images.
|
# with the [TAG] value corresponding the base of the tag to give the Docker
|
||||||
|
# images and the 2nd value being the architecture to build snaps for.
|
||||||
# Values should be something like `v0.34.0` or `nightly`. The given value is
|
# Values should be something like `v0.34.0` or `nightly`. The given value is
|
||||||
# only the base of the tag because the things like the CPU architecture are
|
# only the base of the tag because the things like the CPU architecture are
|
||||||
# also added to the full tag.
|
# also added to the full tag.
|
||||||
@@ -13,12 +14,18 @@ IFS=$'\n\t'
|
|||||||
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
|
|
||||||
TAG_BASE="$1" # Eg. v0.35.0 or nightly
|
TAG_BASE="$1" # Eg. v0.35.0 or nightly
|
||||||
|
if [ -z "$TAG_BASE" ]; then
|
||||||
|
echo "We cannot tag Docker images with an empty string!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
source "$WORK_DIR/lib/common"
|
source "$WORK_DIR/lib/common"
|
||||||
|
ParseRequestedArch "${2}"
|
||||||
|
|
||||||
# Creates and pushes all Docker images aliases for all architectures.
|
# Creates and pushes all Docker images aliases for the requested architectures
|
||||||
# If the value of the global variable TAG_BASE is a version tag such as
|
# set in the environment variable ALL_REQUESTED_ARCH. If the value of the
|
||||||
# v0.35.0, the "latest" tag is also updated. Tags without the architecture part
|
# global variable TAG_BASE is a version tag such as v0.35.0, the "latest" tag
|
||||||
# are also created for the default architecture.
|
# is also updated. Tags without the architecture part are also created for the
|
||||||
|
# default architecture.
|
||||||
# As an example, for amd64 (the default architecture) and the tag v0.35.0, the
|
# As an example, for amd64 (the default architecture) and the tag v0.35.0, the
|
||||||
# following tags would be created:
|
# following tags would be created:
|
||||||
# - certbot/certbot:v0.35.0
|
# - certbot/certbot:v0.35.0
|
||||||
@@ -30,14 +37,15 @@ source "$WORK_DIR/lib/common"
|
|||||||
# For other tags such as "nightly", aliases are only created for the default
|
# For other tags such as "nightly", aliases are only created for the default
|
||||||
# architecture where the tag "nightly" would be used without an architecture
|
# architecture where the tag "nightly" would be used without an architecture
|
||||||
# part.
|
# part.
|
||||||
# Usage: TagAndPushForAllArch [IMAGE NAME]
|
# Usage: TagAndPushForAllRequestedArch [IMAGE NAME]
|
||||||
# where [IMAGE NAME] is the name of the Docker image in the Docker repository
|
# where [IMAGE NAME] is the name of the Docker image in the Docker repository
|
||||||
# such as "certbot" or "dns-cloudflare".
|
# such as "certbot" or "dns-cloudflare".
|
||||||
# Read globals:
|
# Read globals:
|
||||||
# * TAG_BASE
|
# * TAG_BASE
|
||||||
TagAndPushForAllArch() {
|
# * ALL_REQUESTED_ARCH
|
||||||
|
TagAndPushForAllRequestedArch() {
|
||||||
DOCKER_REPO="${DOCKER_HUB_ORG}/${1}"
|
DOCKER_REPO="${DOCKER_HUB_ORG}/${1}"
|
||||||
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
|
for TARGET_ARCH in "${ALL_REQUESTED_ARCH[@]}"; do
|
||||||
docker push "${DOCKER_REPO}:${TARGET_ARCH}-${TAG_BASE}"
|
docker push "${DOCKER_REPO}:${TARGET_ARCH}-${TAG_BASE}"
|
||||||
|
|
||||||
if [[ "${TAG_BASE}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
if [[ "${TAG_BASE}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
@@ -56,9 +64,9 @@ TagAndPushForAllArch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Step 1: Certbot core Docker
|
# Step 1: Certbot core Docker
|
||||||
TagAndPushForAllArch "certbot"
|
TagAndPushForAllRequestedArch "certbot"
|
||||||
|
|
||||||
# Step 2: Certbot DNS plugins Docker images
|
# Step 2: Certbot DNS plugins Docker images
|
||||||
for plugin in "${CERTBOT_PLUGINS[@]}"; do
|
for plugin in "${CERTBOT_PLUGINS[@]}"; do
|
||||||
TagAndPushForAllArch "${plugin}"
|
TagAndPushForAllRequestedArch "${plugin}"
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -31,3 +31,23 @@ export CERTBOT_PLUGINS=(
|
|||||||
"dns-linode"
|
"dns-linode"
|
||||||
"dns-sakuracloud"
|
"dns-sakuracloud"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Parses the requested architecture string and sets ALL_REQUESTED_ARCH to
|
||||||
|
# result.
|
||||||
|
# Usage: ParseRequestedArch [all|amd64|arm32v6|arm64v8]
|
||||||
|
ParseRequestedArch() {
|
||||||
|
REQUESTED_ARCH="${1}"
|
||||||
|
if [[ "${REQUESTED_ARCH}" == "all" ]]; then
|
||||||
|
ALL_REQUESTED_ARCH=("${ALL_TARGET_ARCH[@]}")
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
|
||||||
|
if [[ "${TARGET_ARCH}" == "${REQUESTED_ARCH}" ]]; then
|
||||||
|
ALL_REQUESTED_ARCH=("${REQUESTED_ARCH}")
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# If we didn't return above, REQUESTED_ARCH has an unexpected value.
|
||||||
|
echo "Unexpected target architecture \"${REQUESTED_ARCH}\"". >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user