Skip to content

Commit fe7894e

Browse files
committed
Support aarch64 as a builder
Images can now be compiled either by an x86 or aarch64 builder. When the builder arch matches the target arch, the image is produced natively (rather than running through emulation). When the builder arch and the target arch differ, the appropriate toolchain is installed and used for image compilation, thus avoiding emulation and slow compile times for all cases. Until this change, the builder was always assumed to be x86-based.
1 parent d0219a1 commit fe7894e

File tree

5 files changed

+70
-24
lines changed

5 files changed

+70
-24
lines changed

Dockerfile.multiarch

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ ARG OS=
22

33
ARG ARCH=
44
ARG TOOLCHAIN=
5+
ARG TOOLCHAIN_PREFIX=
56
ARG OPENSSL_TARGET=
67

78
ARG OPENSSL_VERSION=
@@ -17,9 +18,9 @@ ARG HAPROXY_SHA256=
1718
ARG LUA_VERSION=
1819
ARG LUA_MD5=
1920

20-
# Build using cross-compilation, with amd64 as the build arch and $ARCH as the host
21+
# Build using cross-compilation, using $TOOLCHAIN to target $ARCH
2122

22-
FROM --platform=linux/amd64 $OS as builder
23+
FROM $OS as builder
2324

2425
ARG ARCH
2526
ARG TOOLCHAIN
@@ -28,14 +29,16 @@ ARG ARCH_FLAGS
2829
RUN dpkg --add-architecture "${ARCH}" && \
2930
apt-get update && \
3031
apt-get install --no-install-recommends -y \
31-
gcc-10-${TOOLCHAIN} libc6-dev-${ARCH}-cross make file libc6-dev perl libtext-template-perl libreadline-dev curl ca-certificates libcrypt-dev:${ARCH}
32+
gcc-10-${TOOLCHAIN} libc6-dev-${ARCH}-cross make file libc6-dev perl libtext-template-perl \
33+
libreadline-dev curl ca-certificates libcrypt-dev:${ARCH} gcc-10 binutils-${TOOLCHAIN} binutils
3234

3335
### OpenSSL
3436

35-
FROM --platform=linux/amd64 builder as ssl
37+
FROM builder as ssl
3638

3739
ARG ARCH
3840
ARG TOOLCHAIN
41+
ARG TOOLCHAIN_PREFIX
3942
ARG ARCH_FLAGS
4043

4144
ARG OPENSSL_VERSION
@@ -46,18 +49,19 @@ RUN curl -OJL https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz &
4649
echo ${OPENSSL_SHA256} openssl-${OPENSSL_VERSION}.tar.gz | sha256sum -c && \
4750
tar zxvf openssl-${OPENSSL_VERSION}.tar.gz && \
4851
cd openssl-${OPENSSL_VERSION} && \
49-
./Configure ${OPENSSL_TARGET} --cross-compile-prefix=/usr/bin/${TOOLCHAIN}- CC=gcc-10 \
52+
./Configure ${OPENSSL_TARGET} --cross-compile-prefix=/usr/bin/${TOOLCHAIN_PREFIX}- CC=gcc-10 \
5053
-march=${ARCH_FLAGS} enable-ec_nistp_64_gcc_128 \
51-
no-shared --prefix=/tmp/openssl --openssldir=/tmp/openssl && \
54+
no-shared --prefix=/tmp/openssl --openssldir=/tmp/openssl --libdir=lib && \
5255
make && \
5356
make install_sw
5457

5558
### PCRE2
5659

57-
FROM --platform=linux/amd64 builder as pcre2
60+
FROM builder as pcre2
5861

5962
ARG ARCH
6063
ARG TOOLCHAIN
64+
ARG TOOLCHAIN_PREFIX
6165
ARG ARCH_FLAGS
6266

6367
ARG PCRE2_VERSION
@@ -67,7 +71,7 @@ RUN curl -OJL "https://github.com/PhilipHazel/pcre2/releases/download/pcre2-${PC
6771
echo ${PCRE2_SHA256} pcre2-${PCRE2_VERSION}.tar.gz | sha256sum -c && \
6872
tar zxvf pcre2-${PCRE2_VERSION}.tar.gz && \
6973
cd pcre2-${PCRE2_VERSION} && \
70-
CC=/usr/bin/${TOOLCHAIN}-gcc-10 CFLAGS="-O3 -march=${ARCH_FLAGS} -g" \
74+
CC=/usr/bin/${TOOLCHAIN_PREFIX}-gcc-10 CFLAGS="-O3 -march=${ARCH_FLAGS} -g" \
7175
./configure --prefix=/tmp/pcre2 --disable-shared --enable-jit --host=${TOOLCHAIN} && \
7276
make install
7377

@@ -77,6 +81,7 @@ FROM builder as lua
7781

7882
ARG ARCH
7983
ARG TOOLCHAIN
84+
ARG TOOLCHAIN_PREFIX
8085
ARG ARCH_FLAGS
8186

8287
ARG LUA_VERSION
@@ -86,22 +91,23 @@ RUN curl -OJL "http://www.lua.org/ftp/lua-${LUA_VERSION}.tar.gz" && \
8691
echo "${LUA_MD5} lua-${LUA_VERSION}.tar.gz" | md5sum -c && \
8792
tar zxf lua-${LUA_VERSION}.tar.gz && \
8893
cd lua-${LUA_VERSION} && \
89-
make CC="/usr/bin/${TOOLCHAIN}-gcc-10" \
94+
make CC="/usr/bin/${TOOLCHAIN_PREFIX}-gcc-10" \
9095
MYCFLAGS="-march=${ARCH_FLAGS} -g" \
91-
AR="/usr/bin/${TOOLCHAIN}-ar rcu" \
92-
RANLIB=/usr/bin/${TOOLCHAIN}-ranlib && \
96+
AR="/usr/bin/${TOOLCHAIN_PREFIX}-ar rcu" \
97+
RANLIB=/usr/bin/${TOOLCHAIN_PREFIX}-ranlib && \
9398
make install INSTALL_TOP=/tmp/lua
9499

95100
### HAProxy
96101

97-
FROM --platform=linux/amd64 builder as haproxy
102+
FROM builder as haproxy
98103

99104
COPY --from=ssl /tmp/openssl /tmp/openssl
100105
COPY --from=pcre2 /tmp/pcre2 /tmp/pcre2
101106
COPY --from=lua /tmp/lua /tmp/lua
102107

103108
ARG ARCH
104109
ARG TOOLCHAIN
110+
ARG TOOLCHAIN_PREFIX
105111
ARG ARCH_FLAGS
106112

107113
ARG HAPROXY_MAJOR
@@ -114,7 +120,7 @@ RUN curl -OJL "http://www.haproxy.org/download/${HAPROXY_MAJOR}/src/haproxy-${HA
114120
make -C haproxy-${HAPROXY_VERSION} \
115121
TARGET=linux-glibc \
116122
ARCH_FLAGS="-march=${ARCH_FLAGS}" \
117-
CC=/usr/bin/${TOOLCHAIN}-gcc-10 \
123+
CC=/usr/bin/${TOOLCHAIN_PREFIX}-gcc-10 \
118124
USE_SLZ=1 \
119125
USE_STATIC_PCRE2=1 USE_PCRE2_JIT=1 PCRE2DIR=/tmp/pcre2 \
120126
USE_OPENSSL=1 SSL_INC=/tmp/openssl/include SSL_LIB=/tmp/openssl/lib \

Dockerfile renamed to Dockerfile.native

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ RUN curl -OJL https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz &
3232
echo ${OPENSSL_SHA256} openssl-${OPENSSL_VERSION}.tar.gz | sha256sum -c && \
3333
tar zxvf openssl-${OPENSSL_VERSION}.tar.gz && \
3434
cd openssl-${OPENSSL_VERSION} && \
35-
./config no-shared --prefix=/tmp/openssl --openssldir=/tmp/openssl && \
35+
./config no-shared --prefix=/tmp/openssl --openssldir=/tmp/openssl --libdir=lib && \
3636
make && \
3737
make test && \
3838
make install_sw
@@ -89,10 +89,10 @@ RUN curl -OJL "http://www.haproxy.org/download/${HAPROXY_MAJOR}/src/haproxy-${HA
8989
echo "${HAPROXY_SHA256} haproxy-${HAPROXY_VERSION}.tar.gz" | sha256sum -c && \
9090
tar zxvf haproxy-${HAPROXY_VERSION}.tar.gz && \
9191
make -C haproxy-${HAPROXY_VERSION} \
92-
TARGET=linux-glibc ARCH=x86_64 \
92+
TARGET=linux-glibc \
9393
USE_SLZ=1 \
9494
USE_STATIC_PCRE2=1 USE_PCRE2_JIT=1 PCRE2DIR=/tmp/pcre2 \
95-
USE_OPENSSL=1 SSL_INC=/tmp/openssl/include SSL_LIB=/tmp/openssl/lib64 \
95+
USE_OPENSSL=1 SSL_INC=/tmp/openssl/include SSL_LIB=/tmp/openssl/lib \
9696
USE_LUA=1 \
9797
USE_PROMEX=1 \
9898
DESTDIR=/tmp/haproxy PREFIX= \
@@ -104,7 +104,7 @@ RUN curl -OJL "http://www.haproxy.org/download/${HAPROXY_MAJOR}/src/haproxy-${HA
104104

105105
### HAProxy runtime image
106106

107-
FROM --platform=linux/amd64 $OS as runtime
107+
FROM $OS as runtime
108108

109109
RUN apt-get update && \
110110
apt-get install --no-install-recommends -y curl ca-certificates

build.sh

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22

33
set -eu
4+
shopt -s extglob
45

56
export OS=debian:bullseye-slim
67
export OPENSSL_VERSION=3.0.8
@@ -39,7 +40,24 @@ echo "Preparing manifest '$MANIFEST_NAME'"
3940

4041
# Build images that require cross-compliation
4142

42-
for buildspec in buildspec.*; do
43+
echo "Builder is an $(uname -m)"
44+
45+
case "$(uname -m)" in
46+
arm64)
47+
CROSS_SPECS=buildspec.!(aarch64)
48+
NATIVE_DOCKER_ARCH=arm64
49+
;;
50+
x86_64)
51+
CROSS_SPECS=buildspec.!(x86_64)
52+
NATIVE_DOCKER_ARCH=amd64
53+
;;
54+
*)
55+
echo "unknown arch"
56+
exit 1
57+
;;
58+
esac
59+
60+
for buildspec in $CROSS_SPECS; do
4361

4462
set -o allexport
4563
source "$buildspec"
@@ -63,6 +81,7 @@ for buildspec in buildspec.*; do
6381
--build-arg ARCH \
6482
--build-arg ARCH_FLAGS \
6583
--build-arg TOOLCHAIN \
84+
--build-arg TOOLCHAIN_PREFIX \
6685
--build-arg OPENSSL_TARGET \
6786
--provenance=false \
6887
--$ACTION \
@@ -78,14 +97,11 @@ done
7897

7998
echo "building native"
8099

81-
# Build "native" amd64 image
82-
83-
ARCH=amd64
84-
IMAGE_NAME=$BASE:$IMAGE_TAG-$ARCH
100+
IMAGE_NAME=$BASE:$IMAGE_TAG-$NATIVE_DOCKER_ARCH
85101

86102
echo "Building '$IMAGE_NAME'..."
87103

88-
docker buildx build -f Dockerfile -t "$IMAGE_NAME" \
104+
docker buildx build -f Dockerfile.native -t "$IMAGE_NAME" \
89105
--build-arg OS \
90106
--build-arg OPENSSL_VERSION \
91107
--build-arg OPENSSL_SHA256 \
@@ -102,7 +118,7 @@ docker buildx build -f Dockerfile -t "$IMAGE_NAME" \
102118

103119
if [ -n "$REALBUILD" ]; then
104120
docker manifest create "$MANIFEST_NAME" --amend "$IMAGE_NAME"
105-
docker manifest annotate --arch=$ARCH "$MANIFEST_NAME" "$IMAGE_NAME"
121+
docker manifest annotate --arch=$NATIVE_DOCKER_ARCH "$MANIFEST_NAME" "$IMAGE_NAME"
106122
docker manifest inspect "$MANIFEST_NAME"
107123

108124
# Push the complete manifest

buildspec.aarch64

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export ARCH_FLAGS=armv8.2-a+fp16+rcpc+dotprod+crypto
2222
# The GNU triplet toolchain for cross-compiling to the specified architecture.
2323
# These are specifically "debian multiarch tuples" per https://wiki.debian.org/Multiarch/Tuples
2424
export TOOLCHAIN=aarch64-linux-gnu
25+
export TOOLCHAIN_PREFIX=aarch64-linux-gnu
2526

2627
# Valid openssl targets are defined in openssl/Configurations/10-main.conf.
2728
export OPENSSL_TARGET=linux-aarch64

buildspec.x86_64

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Target architecture in docker parlance. This is essentially $GOARCH, per the
2+
# manifest spec at https://docs.docker.com/registry/spec/manifest-v2-2/
3+
#
4+
# The "linux/" OS prefix is assumed.
5+
#
6+
export ARCH=amd64
7+
8+
# The advertised variant that will be used in the manifest.
9+
export VARIANT=
10+
11+
# Generic x86-64
12+
#
13+
# https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
14+
export ARCH_FLAGS=x86-64
15+
16+
# The GNU triplet toolchain for cross-compiling to the specified architecture.
17+
# These are specifically "debian multiarch tuples" per https://wiki.debian.org/Multiarch/Tuples
18+
export TOOLCHAIN=x86-64-linux-gnu
19+
export TOOLCHAIN_PREFIX=x86_64-linux-gnu
20+
21+
# Valid openssl targets are defined in openssl/Configurations/10-main.conf.
22+
export OPENSSL_TARGET=linux-x86_64
23+

0 commit comments

Comments
 (0)