go-debos / debos

Debian OS builder
Apache License 2.0
533 stars 136 forks source link

docker: Add arm64-based Dockerfile #505

Open tboehler1 opened 3 months ago

tboehler1 commented 3 months ago

I needed an arm64-based Docker image to run debos but it seems like you don't provide one.

This PR contains the Dockerfile I use to build images on arm64. Arch Linux specific things (notably the archlinux-keyring) aren't installed and handled at all, but seeing that https://github.com/go-debos/debos/issues/483 is open this might be put into a separate conatiner for building Arch Linux images anyway?

Feel free to merge if you're okay with the Dockerfile and want to support arm64-based Docker images upstream. Of course I'm open to improve this as well.

Thanks!

obbardc commented 3 months ago

This isn't built in ci? :-)

Also, would it be possible to just extend the actions to set the build arch to arm64 with the same Dockerfile ?

tboehler1 commented 3 months ago

With actions you mean the steps running in the CI? I'm not familiar with the GitHub CI at all, I'm not sure if I can be of help there.

I imagine using ARG in the Dockerfile and passing arm64 with --build-arg ARCH=arm64 doesn't work because there is some logic involved with the different architectures, i.e. arm64 would imply using arm64v8/debian but it would also imply installing linux-image-arm64 and not installing user-mode-linux (as it's not available for arm64). I'm not aware of Docker being able to handle logic this in Dockerfiles but do correct me if I'm wrong.

nbuchwitz commented 3 weeks ago

Thanks, @tboehler1 for bringing this up. A native docker container for arm64 builds is a good idea as it encapsulates everything, but keeps the huge benefit when it comes to build times.

I agree with @obbardc, that it would be better to maintain a single Dockerfile for all target architectures. This can be done with dockers multiarch support like this:

diff --git a/docker/Dockerfile b/docker/Dockerfile
index dd4d3ab..9ef83aa 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,9 +1,10 @@
 # Global ARGs shared by all stages
+ARG ARCH=
 ARG DEBIAN_FRONTEND=noninteractive
 ARG GOPATH=/usr/local/go

 ### first stage - builder ###
-FROM debian:bookworm-slim as builder
+FROM ${ARCH}debian:bookworm-slim AS builder

 ARG DEBIAN_FRONTEND
 ARG GOPATH
@@ -34,7 +35,24 @@ COPY docker/get-archlinux-keyring.sh /
 RUN /get-archlinux-keyring.sh /arch-keyring

 ### second stage - runner ###
-FROM debian:bookworm-slim as runner
+FROM ${ARCH}debian:bookworm-slim AS runner-amd64
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+        linux-image-amd64 \
+        qemu-system-x86 \
+        user-mode-linux && \
+    rm -rf /var/lib/apt/lists/*
+
+FROM ${ARCH}debian:bookworm-slim AS runner-arm64
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+        linux-image-arm64 \
+        qemu-system-arm \
+       # fixes: qemu-system-aarch64: failed to find romfile "efi-virtio.rom"
+       ipxe-qemu && \
+    rm -rf /var/lib/apt/lists/*
+
+FROM runner-${TARGETARCH} AS runner

 ARG DEBIAN_FRONTEND
 ARG GOPATH
@@ -78,11 +96,9 @@ RUN apt-get update && \
         pigz \
         libostree-1-1 \
         libslirp-helper \
-        linux-image-amd64 \
         openssh-client \
         parted \
         pkg-config \
-        qemu-system-x86 \
         qemu-user-static \
         qemu-utils \
         rsync \
@@ -91,7 +107,6 @@ RUN apt-get update && \
         systemd-resolved \
         u-boot-tools \
         unzip \
-        user-mode-linux \
         xfsprogs \
         xz-utils \
         zip \

This would allow to override certain arch specific stuff in a separate stage. Even diffrent base images depending on the target arch are possible.

Build is done with explicit target arch:

docker buildx build --platform linux/arm64/v8 -f docker/Dockerfile -t godebos/debos .

and without:

docker buildx build -f docker/Dockerfile -t godebos/debos .

or

docker build -f docker/Dockerfile -t godebos/debos .

Even multiple architectures can be build at once:

docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 -f docker/Dockerfile -t godebos/debos .

Note that the list of packages for the specific and generic stage needs probably some review. Haven't checked @tboehler1 s list in detail against the original one.

The CI pipeline already uses docker/setup-buildx-action@v3, which supports the platforms parameter. So it would be really easy to build amd64 and arm64 images automatically.

obbardc commented 3 weeks ago

@nbuchwitz I agree with your solution. Can you open a PR?

nbuchwitz commented 3 weeks ago

Sure, @obbardc. I've created a feature branch in my fork https://github.com/nbuchwitz/debos/tree/devel/add-arm64-support

Need to rework some of the piplines to ensure that the multiarch container is tested properly (mostly migrate the build artifacts to oci exports). After that I will open the PR (probably later today or tomorrow).

@tboehler1 I've added you as co autor on the commit message.