From 9db87c369b92f37f2f62da45c77c1a1f4be9d72b Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Tue, 9 Sep 2025 12:07:25 -0400 Subject: [PATCH 1/9] Enhance platform support in Docker build scripts for Boulder - Added TARGETPLATFORM argument to Containerfile for architecture-specific builds. - Updated container-build.sh to detect architecture and set appropriate platform. - Modified make-deb.sh to dynamically set the architecture in the .deb package. --- Containerfile | 8 ++++++- tools/container-build.sh | 45 +++++++++++++++++++++++++++------------- tools/make-deb.sh | 15 ++++++++++++-- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/Containerfile b/Containerfile index 92276aa6d30..a7162b0be4d 100644 --- a/Containerfile +++ b/Containerfile @@ -6,13 +6,19 @@ FROM docker.io/ubuntu:24.04 AS builder ARG COMMIT_ID ARG GO_VERSION ARG VERSION +ARG TARGETPLATFORM ENV DEBIAN_FRONTEND=noninteractive RUN apt-get --assume-yes --no-install-recommends --update install \ ca-certificates curl gcc git gnupg2 libc6-dev COPY tools/fetch-and-verify-go.sh /tmp -RUN /tmp/fetch-and-verify-go.sh ${GO_VERSION} +RUN case "${TARGETPLATFORM}" in \ + "linux/amd64") PLATFORM="linux-amd64" ;; \ + "linux/arm64") PLATFORM="linux-arm64" ;; \ + *) echo "Unsupported platform: ${TARGETPLATFORM}" && exit 1 ;; \ + esac && \ + /tmp/fetch-and-verify-go.sh ${GO_VERSION} ${PLATFORM} RUN tar -C /opt -xzf go.tar.gz ENV PATH="/opt/go/bin:${PATH}" diff --git a/tools/container-build.sh b/tools/container-build.sh index 735332b6a67..285c96fa84d 100755 --- a/tools/container-build.sh +++ b/tools/container-build.sh @@ -7,36 +7,53 @@ set -ex -# Without this, `go install` produces: -# # runtime/cgo -# gcc: error: unrecognized command-line option '-m64' -if [ "$(uname -m)" = "arm64" ]; then - export DOCKER_DEFAULT_PLATFORM=linux/amd64 -fi - if [ -z "${GO_VERSION}" ] ; then echo "GO_VERSION not set" exit 1 fi -ARCH="$(uname -m)" COMMIT_ID="$(git rev-parse --short=8 HEAD)" VERSION="${GO_VERSION}.$(date +%s)" +# Detect architecture to build for (allow override via DOCKER_DEFAULT_PLATFORM) +if [ -n "${DOCKER_DEFAULT_PLATFORM}" ]; then + PLATFORM="${DOCKER_DEFAULT_PLATFORM}" +else + case "$(uname -m)" in + "x86_64") PLATFORM="linux/amd64" ;; + "aarch64"|"arm64") PLATFORM="linux/arm64" ;; + *) echo "Unsupported architecture: $(uname -m)" && exit 1 ;; + esac +fi + +# Extract architecture from platform +case "$PLATFORM" in + "linux/amd64") ARCH="amd64" ;; + "linux/arm64") ARCH="arm64" ;; + *) echo "Unsupported platform: ${PLATFORM}" && exit 1 ;; +esac + +# Create platform-specific image docker buildx build \ --file Containerfile \ + --platform "$PLATFORM" \ --build-arg "COMMIT_ID=${COMMIT_ID}" \ --build-arg "GO_VERSION=${GO_VERSION}" \ --build-arg "VERSION=${VERSION}" \ + --tag "boulder:${VERSION}-${ARCH}" \ --tag "boulder:${VERSION}" \ --tag "boulder:${COMMIT_ID}" \ --tag boulder \ + --load \ . -docker run boulder tar -C /opt/boulder -cpz . > "./boulder-${VERSION}-${COMMIT_ID}.${ARCH}.tar.gz" . -# Produces e.g. boulder-1.25.0.1754519595-591c0545.x86_64.deb +# Create tarball +docker run "boulder:${VERSION}-${ARCH}" tar -C /opt/boulder -cpz . > "./boulder-${VERSION}-${COMMIT_ID}.${ARCH}.tar.gz" + +# Create .deb package docker run -v .:/boulderrepo \ - -e "COMMIT_ID=$(git rev-parse --short=8 HEAD)" \ - -e "VERSION=${VERSION}" \ - boulder \ - /boulderrepo/tools/make-deb.sh + -e "COMMIT_ID=${COMMIT_ID}" \ + -e "VERSION=${VERSION}" \ + -e "ARCH=${ARCH}" \ + "boulder:${VERSION}-${ARCH}" \ + /boulderrepo/tools/make-deb.sh diff --git a/tools/make-deb.sh b/tools/make-deb.sh index 56d0a4ae899..89fdb5c8b77 100755 --- a/tools/make-deb.sh +++ b/tools/make-deb.sh @@ -15,13 +15,24 @@ BUILD="$(mktemp -d)" mkdir -p "${BUILD}/opt" cp -a /opt/boulder "${BUILD}/opt/boulder" +# Determine architecture - use ARCH env var if set, otherwise detect from uname +if [ -n "${ARCH:-}" ]; then + DEB_ARCH="${ARCH}" +else + case "$(uname -m)" in + "x86_64") DEB_ARCH="amd64" ;; + "aarch64"|"arm64") DEB_ARCH="arm64" ;; + *) echo "Unsupported architecture: $(uname -m)" && exit 1 ;; + esac +fi + mkdir -p "${BUILD}/DEBIAN" cat > "${BUILD}/DEBIAN/control" <<-EOF Package: boulder Version: 1:${VERSION} License: Mozilla Public License v2.0 Vendor: ISRG -Architecture: amd64 +Architecture: ${DEB_ARCH} Maintainer: Community Section: default Priority: extra @@ -29,4 +40,4 @@ Homepage: https://github.com/letsencrypt/boulder Description: Boulder is an ACME-compatible X.509 Certificate Authority EOF -dpkg-deb -Zgzip -b "${BUILD}" "boulder-${VERSION}-${COMMIT_ID}.x86_64.deb" +dpkg-deb -Zgzip -b "${BUILD}" "boulder-${VERSION}-${COMMIT_ID}.${DEB_ARCH}.deb" From d3cfabe5bb5dc0730994becb3833ad804e4ea90e Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Wed, 10 Sep 2025 08:04:02 -0400 Subject: [PATCH 2/9] refactor: streamline Docker build and .deb packaging process --- tools/container-build.sh | 12 ++++++------ tools/make-deb.sh | 28 ++++++++++------------------ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/tools/container-build.sh b/tools/container-build.sh index 285c96fa84d..27fd2ff03eb 100755 --- a/tools/container-build.sh +++ b/tools/container-build.sh @@ -33,6 +33,9 @@ case "$PLATFORM" in *) echo "Unsupported platform: ${PLATFORM}" && exit 1 ;; esac +# Define single tag to avoid collisions and redundancy +TAG="boulder:${VERSION}-${ARCH}" + # Create platform-specific image docker buildx build \ --file Containerfile \ @@ -40,20 +43,17 @@ docker buildx build \ --build-arg "COMMIT_ID=${COMMIT_ID}" \ --build-arg "GO_VERSION=${GO_VERSION}" \ --build-arg "VERSION=${VERSION}" \ - --tag "boulder:${VERSION}-${ARCH}" \ - --tag "boulder:${VERSION}" \ - --tag "boulder:${COMMIT_ID}" \ - --tag boulder \ + --tag "${TAG}" \ --load \ . # Create tarball -docker run "boulder:${VERSION}-${ARCH}" tar -C /opt/boulder -cpz . > "./boulder-${VERSION}-${COMMIT_ID}.${ARCH}.tar.gz" +docker run "${TAG}" tar -C /opt/boulder -cpz . > "./boulder-${VERSION}-${COMMIT_ID}.${ARCH}.tar.gz" # Create .deb package docker run -v .:/boulderrepo \ -e "COMMIT_ID=${COMMIT_ID}" \ -e "VERSION=${VERSION}" \ -e "ARCH=${ARCH}" \ - "boulder:${VERSION}-${ARCH}" \ + "${TAG}" \ /boulderrepo/tools/make-deb.sh diff --git a/tools/make-deb.sh b/tools/make-deb.sh index 89fdb5c8b77..d39ff165f65 100755 --- a/tools/make-deb.sh +++ b/tools/make-deb.sh @@ -1,38 +1,30 @@ #!/usr/bin/env bash # -# Produce a .deb from a built Boulder plus helper files. +# Produce a .deb package from a built Boulder container. # -# This script expects to run on Ubuntu, as configured on GitHub Actions runners -# (with curl, make, and git installed). +# This script is executed inside the Boulder Docker container by container-build.sh. +# It packages the Boulder binary and assets into a Debian package for distribution. # # -e Stops execution in the instance of a command or pipeline error. # -u Treat unset variables as an error and exit immediately. set -eu cd "$(realpath -- "$(dirname -- "$0")")/.." -BUILD="$(mktemp -d)" +if [ -z "${VERSION:-}" ]; then echo "VERSION not set"; exit 1; fi +if [ -z "${COMMIT_ID:-}" ]; then echo "COMMIT_ID not set"; exit 1; fi +if [ -z "${ARCH:-}" ]; then echo "ARCH not set"; exit 1; fi +BUILD="$(mktemp -d)" mkdir -p "${BUILD}/opt" cp -a /opt/boulder "${BUILD}/opt/boulder" -# Determine architecture - use ARCH env var if set, otherwise detect from uname -if [ -n "${ARCH:-}" ]; then - DEB_ARCH="${ARCH}" -else - case "$(uname -m)" in - "x86_64") DEB_ARCH="amd64" ;; - "aarch64"|"arm64") DEB_ARCH="arm64" ;; - *) echo "Unsupported architecture: $(uname -m)" && exit 1 ;; - esac -fi - mkdir -p "${BUILD}/DEBIAN" -cat > "${BUILD}/DEBIAN/control" <<-EOF +cat >"${BUILD}/DEBIAN/control" <<-EOF Package: boulder Version: 1:${VERSION} License: Mozilla Public License v2.0 Vendor: ISRG -Architecture: ${DEB_ARCH} +Architecture: ${ARCH} Maintainer: Community Section: default Priority: extra @@ -40,4 +32,4 @@ Homepage: https://github.com/letsencrypt/boulder Description: Boulder is an ACME-compatible X.509 Certificate Authority EOF -dpkg-deb -Zgzip -b "${BUILD}" "boulder-${VERSION}-${COMMIT_ID}.${DEB_ARCH}.deb" +dpkg-deb -Zgzip -b "${BUILD}" "boulder-${VERSION}-${COMMIT_ID}.${ARCH}.deb" From 5d7d235ebbacadafe49f41c4ec9e64cc845edf13 Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Wed, 10 Sep 2025 08:25:16 -0400 Subject: [PATCH 3/9] refactor: clarify architecture and platform determination --- tools/container-build.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tools/container-build.sh b/tools/container-build.sh index 27fd2ff03eb..9876ca7cc0f 100755 --- a/tools/container-build.sh +++ b/tools/container-build.sh @@ -15,21 +15,25 @@ fi COMMIT_ID="$(git rev-parse --short=8 HEAD)" VERSION="${GO_VERSION}.$(date +%s)" -# Detect architecture to build for (allow override via DOCKER_DEFAULT_PLATFORM) +# Determine what architecture to build for if [ -n "${DOCKER_DEFAULT_PLATFORM}" ]; then + # User specified a platform override PLATFORM="${DOCKER_DEFAULT_PLATFORM}" else - case "$(uname -m)" in - "x86_64") PLATFORM="linux/amd64" ;; - "aarch64"|"arm64") PLATFORM="linux/arm64" ;; - *) echo "Unsupported architecture: $(uname -m)" && exit 1 ;; + # No override - detect from current machine + MACHINE_ARCH=$(uname -m) + case "${MACHINE_ARCH}" in + x86_64) PLATFORM="linux/amd64" ;; + aarch64) PLATFORM="linux/arm64" ;; + arm64) PLATFORM="linux/arm64" ;; + *) echo "Unsupported machine architecture: ${MACHINE_ARCH}" && exit 1 ;; esac fi -# Extract architecture from platform -case "$PLATFORM" in - "linux/amd64") ARCH="amd64" ;; - "linux/arm64") ARCH="arm64" ;; +# Convert platform to short architecture name for file naming +case "${PLATFORM}" in + linux/amd64) ARCH="amd64" ;; + linux/arm64) ARCH="arm64" ;; *) echo "Unsupported platform: ${PLATFORM}" && exit 1 ;; esac @@ -45,6 +49,7 @@ docker buildx build \ --build-arg "VERSION=${VERSION}" \ --tag "${TAG}" \ --load \ + --progress=plain \ . # Create tarball From f135e1f51da900f99d425872cf66b9158dbdea32 Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Thu, 11 Sep 2025 15:37:40 -0400 Subject: [PATCH 4/9] ci: build and publish multi-arch amd64/arm64 artifacts --- .dockerignore | 1 + .github/workflows/release.yml | 134 ++++++++++++++++++++++++++---- .github/workflows/try-release.yml | 17 +++- .gitignore | 2 + 4 files changed, 133 insertions(+), 21 deletions(-) diff --git a/.dockerignore b/.dockerignore index 8797cc5274e..05dc17082f2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,3 +8,4 @@ test/certs/webpki test/certs/.softhsm-tokens .git .gocache +.github diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 61c710e7c1c..ee88665a42d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,16 +10,23 @@ on: - '**' jobs: - push-release: + build-artifacts: strategy: fail-fast: false matrix: - GO_VERSION: - - "1.25.0" - runs-on: ubuntu-24.04 + include: + - GO_VERSION: "1.25.0" + ARCH: "amd64" + RUNNER: "ubuntu-24.04" + - GO_VERSION: "1.25.0" + ARCH: "arm64" + RUNNER: "ubuntu-24.04-arm" + runs-on: ${{ matrix.RUNNER }} permissions: contents: write packages: write + outputs: + version: ${{ steps.version.outputs.version }} steps: - uses: actions/checkout@v4 with: @@ -29,20 +36,61 @@ jobs: - name: Verify release ancestry run: ./tools/verify-release-ancestry.sh "$GITHUB_SHA" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set version output + id: version + run: | + VERSION="${{ matrix.GO_VERSION }}.$(date +%s)" + echo "version=${VERSION}" >> $GITHUB_OUTPUT + - name: Build Boulder container and .deb id: build env: GO_VERSION: ${{ matrix.GO_VERSION }} + DOCKER_DEFAULT_PLATFORM: linux/${{ matrix.ARCH }} run: ./tools/container-build.sh - - name: Tag Boulder container - run: docker tag boulder "ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${{ matrix.GO_VERSION }}" + - name: Export container image for multi-platform + run: | + VERSION="${{ steps.version.outputs.version }}" + docker save "boulder:${VERSION}-${{ matrix.ARCH }}" | gzip > "boulder-image-${{ matrix.ARCH }}.tar.gz" + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: boulder-${{ matrix.ARCH }} + path: | + boulder*.deb + boulder*.tar.gz + boulder-image-${{ matrix.ARCH }}.tar.gz + retention-days: 1 - - name: Compute checksums - id: checksums - # The files listed on this line must be identical to the files uploaded - # in the last step. - run: sha256sum boulder*.deb boulder*.tar.gz >| boulder-${{ matrix.GO_VERSION }}.$(date +%s)-$(git rev-parse --short=8 HEAD).checksums.txt + create-release: + needs: build-artifacts + runs-on: ubuntu-24.04 + permissions: + contents: write + packages: write + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: '0' + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + - name: Prepare release files + run: | + # Move all .deb and .tar.gz files to current directory + find artifacts/ -name "*.deb" -o -name "*.tar.gz" | grep -v "boulder-image-" | xargs -I {} cp {} . + + # Compute checksums for release files only + sha256sum boulder*.deb boulder*.tar.gz >| boulder-${{ needs.build-artifacts.outputs.version }}.$(git rev-parse --short=8 HEAD).checksums.txt - name: Create release env: @@ -57,16 +105,68 @@ jobs: # https://cli.github.com/manual/gh_release_upload run: gh release upload "${GITHUB_REF_NAME}" boulder*.deb boulder*.tar.gz boulder*.checksums.txt - - name: Build ct-test-srv container - run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.ref_name }}-go${{ matrix.GO_VERSION }}" + push-images: + needs: build-artifacts + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Download container images + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + - name: Load and tag images + run: | + # Load architecture-specific images + docker load < artifacts/boulder-amd64/boulder-image-amd64.tar.gz + docker load < artifacts/boulder-arm64/boulder-image-arm64.tar.gz + + VERSION="${{ needs.build-artifacts.outputs.version }}" + BASE_TAG="ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${VERSION}" + + # Tag with architecture-specific tags for manifest creation + docker tag "boulder:${VERSION}-amd64" "${BASE_TAG}-amd64" + docker tag "boulder:${VERSION}-arm64" "${BASE_TAG}-arm64" - name: Login to ghcr.io run: printenv GITHUB_TOKEN | docker login ghcr.io -u "${{ github.actor }}" --password-stdin env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Push Boulder container - run: docker push "ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${{ matrix.GO_VERSION }}" + - name: Push architecture-specific images + run: | + VERSION="${{ needs.build-artifacts.outputs.version }}" + BASE_TAG="ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${VERSION}" + docker push "${BASE_TAG}-amd64" + docker push "${BASE_TAG}-arm64" + + - name: Create and push multi-platform manifest + run: | + VERSION="${{ needs.build-artifacts.outputs.version }}" + BASE_TAG="ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${VERSION}" + + docker buildx imagetools create -t "${BASE_TAG}" \ + "${BASE_TAG}-amd64" \ + "${BASE_TAG}-arm64" - - name: Push ct-test-srv container - run: docker push "ghcr.io/letsencrypt/ct-test-srv:${{ github.ref_name }}-go${{ matrix.GO_VERSION }}" + - name: Build and push ct-test-srv multi-platform + run: | + VERSION="${{ needs.build-artifacts.outputs.version }}" + docker buildx build . \ + --build-arg "GO_VERSION=${{ needs.build-artifacts.outputs.version }}" \ + -f test/ct-test-srv/Dockerfile \ + --platform linux/amd64,linux/arm64 \ + -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.ref_name }}-go${VERSION}" \ + --push diff --git a/.github/workflows/try-release.yml b/.github/workflows/try-release.yml index 1cd6270b105..b0c6b0e5a77 100644 --- a/.github/workflows/try-release.yml +++ b/.github/workflows/try-release.yml @@ -18,18 +18,27 @@ jobs: strategy: fail-fast: false matrix: - GO_VERSION: - - "1.25.0" - runs-on: ubuntu-24.04 + include: + - GO_VERSION: "1.25.0" + ARCH: "amd64" + RUNNER: "ubuntu-24.04" + - GO_VERSION: "1.25.0" + ARCH: "arm64" + RUNNER: "ubuntu-24.04-arm" + runs-on: ${{ matrix.RUNNER }} steps: - uses: actions/checkout@v4 with: persist-credentials: false + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build Boulder container and .deb id: build env: GO_VERSION: ${{ matrix.GO_VERSION }} + DOCKER_DEFAULT_PLATFORM: linux/${{ matrix.ARCH }} run: ./tools/container-build.sh - name: Compute checksums @@ -47,4 +56,4 @@ jobs: run: cat boulder*.checksums.txt - name: Build ct-test-srv container - run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.sha }}-go${{ matrix.GO_VERSION }}" + run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.sha }}-go${{ matrix.GO_VERSION }}-${{ matrix.ARCH }}" --load diff --git a/.gitignore b/.gitignore index 769b54767cf..28c283ed383 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ *.a *.so *.pyc +boulder-*.deb +boulder-*.tar.gz # Folders _obj From 908a45af9ebee3ac086da5413e72639716c30a6d Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Thu, 11 Sep 2025 16:02:36 -0400 Subject: [PATCH 5/9] build: Use commit timestamp for reproducible builds --- .github/workflows/release.yml | 4 +++- tools/container-build.sh | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee88665a42d..4793b738480 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,9 @@ jobs: - name: Set version output id: version run: | - VERSION="${{ matrix.GO_VERSION }}.$(date +%s)" + # Use commit timestamp for reproducible builds + COMMIT_TIMESTAMP="$(git show -s --format=%ct HEAD)" + VERSION="${{ matrix.GO_VERSION }}.${COMMIT_TIMESTAMP}" echo "version=${VERSION}" >> $GITHUB_OUTPUT - name: Build Boulder container and .deb diff --git a/tools/container-build.sh b/tools/container-build.sh index 9876ca7cc0f..5bec0af0650 100755 --- a/tools/container-build.sh +++ b/tools/container-build.sh @@ -13,7 +13,9 @@ if [ -z "${GO_VERSION}" ] ; then fi COMMIT_ID="$(git rev-parse --short=8 HEAD)" -VERSION="${GO_VERSION}.$(date +%s)" +# Use commit timestamp for reproducible builds +COMMIT_TIMESTAMP="$(git show -s --format=%ct HEAD)" +VERSION="${GO_VERSION}.${COMMIT_TIMESTAMP}" # Determine what architecture to build for if [ -n "${DOCKER_DEFAULT_PLATFORM}" ]; then From f8226f87a3dcd522497e08579bac18c6d45fb169 Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Thu, 11 Sep 2025 16:16:15 -0400 Subject: [PATCH 6/9] ci: Use dynamic repository owner for GHCR image paths --- .github/workflows/release.yml | 8 ++++---- .github/workflows/try-release.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4793b738480..8fdc183fbe3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -136,7 +136,7 @@ jobs: docker load < artifacts/boulder-arm64/boulder-image-arm64.tar.gz VERSION="${{ needs.build-artifacts.outputs.version }}" - BASE_TAG="ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${VERSION}" + BASE_TAG="ghcr.io/${{ github.repository_owner }}/boulder:${{ github.ref_name }}-go${VERSION}" # Tag with architecture-specific tags for manifest creation docker tag "boulder:${VERSION}-amd64" "${BASE_TAG}-amd64" @@ -150,14 +150,14 @@ jobs: - name: Push architecture-specific images run: | VERSION="${{ needs.build-artifacts.outputs.version }}" - BASE_TAG="ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${VERSION}" + BASE_TAG="ghcr.io/${{ github.repository_owner }}/boulder:${{ github.ref_name }}-go${VERSION}" docker push "${BASE_TAG}-amd64" docker push "${BASE_TAG}-arm64" - name: Create and push multi-platform manifest run: | VERSION="${{ needs.build-artifacts.outputs.version }}" - BASE_TAG="ghcr.io/letsencrypt/boulder:${{ github.ref_name }}-go${VERSION}" + BASE_TAG="ghcr.io/${{ github.repository_owner }}/boulder:${{ github.ref_name }}-go${VERSION}" docker buildx imagetools create -t "${BASE_TAG}" \ "${BASE_TAG}-amd64" \ @@ -170,5 +170,5 @@ jobs: --build-arg "GO_VERSION=${{ needs.build-artifacts.outputs.version }}" \ -f test/ct-test-srv/Dockerfile \ --platform linux/amd64,linux/arm64 \ - -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.ref_name }}-go${VERSION}" \ + -t "ghcr.io/${{ github.repository_owner }}/ct-test-srv:${{ github.ref_name }}-go${VERSION}" \ --push diff --git a/.github/workflows/try-release.yml b/.github/workflows/try-release.yml index b0c6b0e5a77..86a3d4a93d0 100644 --- a/.github/workflows/try-release.yml +++ b/.github/workflows/try-release.yml @@ -56,4 +56,4 @@ jobs: run: cat boulder*.checksums.txt - name: Build ct-test-srv container - run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.sha }}-go${{ matrix.GO_VERSION }}-${{ matrix.ARCH }}" --load + run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/${{ github.repository_owner }}/ct-test-srv:${{ github.sha }}-go${{ matrix.GO_VERSION }}-${{ matrix.ARCH }}" --load From 09027e835f2c1c7577ac1abe66e86e8f900d87a8 Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Thu, 11 Sep 2025 17:13:57 -0400 Subject: [PATCH 7/9] fix: Correct GO_VERSION build arg in release workflow --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8fdc183fbe3..1587aec37f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,6 +27,7 @@ jobs: packages: write outputs: version: ${{ steps.version.outputs.version }} + go_version: ${{ matrix.GO_VERSION }} steps: - uses: actions/checkout@v4 with: @@ -167,7 +168,7 @@ jobs: run: | VERSION="${{ needs.build-artifacts.outputs.version }}" docker buildx build . \ - --build-arg "GO_VERSION=${{ needs.build-artifacts.outputs.version }}" \ + --build-arg "GO_VERSION=${{ needs.build-artifacts.outputs.go_version }}" \ -f test/ct-test-srv/Dockerfile \ --platform linux/amd64,linux/arm64 \ -t "ghcr.io/${{ github.repository_owner }}/ct-test-srv:${{ github.ref_name }}-go${VERSION}" \ From cdcbea6445286a1a93f33baf843275997425d0ac Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Fri, 12 Sep 2025 05:22:23 -0400 Subject: [PATCH 8/9] build: Add generic tags to container image This improves the local development experience by providing stable, predictable tags to use for testing, without affecting the architecture-specific tags required by the CI/release process. --- tools/container-build.sh | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tools/container-build.sh b/tools/container-build.sh index 5bec0af0650..627a399710d 100755 --- a/tools/container-build.sh +++ b/tools/container-build.sh @@ -25,42 +25,43 @@ else # No override - detect from current machine MACHINE_ARCH=$(uname -m) case "${MACHINE_ARCH}" in - x86_64) PLATFORM="linux/amd64" ;; - aarch64) PLATFORM="linux/arm64" ;; - arm64) PLATFORM="linux/arm64" ;; - *) echo "Unsupported machine architecture: ${MACHINE_ARCH}" && exit 1 ;; + x86_64) PLATFORM="linux/amd64" ;; + aarch64) PLATFORM="linux/arm64" ;; + arm64) PLATFORM="linux/arm64" ;; + *) echo "Unsupported machine architecture: ${MACHINE_ARCH}" && exit 1 ;; esac fi # Convert platform to short architecture name for file naming case "${PLATFORM}" in - linux/amd64) ARCH="amd64" ;; - linux/arm64) ARCH="arm64" ;; - *) echo "Unsupported platform: ${PLATFORM}" && exit 1 ;; + linux/amd64) ARCH="amd64" ;; + linux/arm64) ARCH="arm64" ;; + *) echo "Unsupported platform: ${PLATFORM}" && exit 1 ;; esac -# Define single tag to avoid collisions and redundancy -TAG="boulder:${VERSION}-${ARCH}" - # Create platform-specific image +# Keep generic tags for standalone use docker buildx build \ --file Containerfile \ --platform "$PLATFORM" \ --build-arg "COMMIT_ID=${COMMIT_ID}" \ --build-arg "GO_VERSION=${GO_VERSION}" \ --build-arg "VERSION=${VERSION}" \ - --tag "${TAG}" \ + --tag "boulder:${VERSION}-${ARCH}" \ + --tag "boulder:${VERSION}" \ + --tag "boulder" \ --load \ --progress=plain \ . # Create tarball -docker run "${TAG}" tar -C /opt/boulder -cpz . > "./boulder-${VERSION}-${COMMIT_ID}.${ARCH}.tar.gz" +docker run "boulder" tar -C /opt/boulder -cpz . \ + > "./boulder-${VERSION}-${COMMIT_ID}.${ARCH}.tar.gz" # Create .deb package docker run -v .:/boulderrepo \ -e "COMMIT_ID=${COMMIT_ID}" \ -e "VERSION=${VERSION}" \ -e "ARCH=${ARCH}" \ - "${TAG}" \ + "boulder" \ /boulderrepo/tools/make-deb.sh From 33ad8530bb818fab3286f168b8c1ab9fe760a9f7 Mon Sep 17 00:00:00 2001 From: Shiloh Heurich Date: Fri, 12 Sep 2025 05:56:47 -0400 Subject: [PATCH 9/9] build: parameterize build and deploy base images --- Containerfile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Containerfile b/Containerfile index a7162b0be4d..be6017ba5e5 100644 --- a/Containerfile +++ b/Containerfile @@ -1,7 +1,10 @@ -# This builds Boulder in a Docker container, then creates an image -# containing just the built Boulder binaries plus some ancillary -# files that are useful for predeployment testing. -FROM docker.io/ubuntu:24.04 AS builder +# This multi-stage build first builds Boulder in a container, then +# creates a minimal image containing the built Boulder binaries and +# ancillary files for pre-deployment testing. +ARG BUILDER_BASE=docker.io/ubuntu:24.04 +ARG FINAL_BASE=docker.io/ubuntu:24.04 + +FROM ${BUILDER_BASE} AS builder ARG COMMIT_ID ARG GO_VERSION @@ -32,7 +35,7 @@ RUN go install \ -mod=vendor \ ./... -FROM docker.io/ubuntu:24.04 +FROM ${FINAL_BASE} ARG VERSION