See attached an example of a multi stage build that creates a container
having only qemu binaries, their libraries, and qemu roms, and nothing
else. It does not even have a shell.
build with:
$ podman build -f qemu.Dockerfile --build-arg QEMU_VERSION=v11.1.0 \
-t test --squash-all
run with:
$ podman run -it --rm test qemu-system-aarch64 --version
QEMU emulator version 11.1.0 (v11.1.0)
Copyright (c) 2003-2026 Fabrice Bellard and the QEMU Project developers
Regards,
Pierrick
FROM debian:13 as build
RUN apt update && apt install -y git build-essential
RUN sed -e 's/Types: deb/Types: deb deb-src/' -i
/etc/apt/sources.list.d/debian.sources
RUN apt update && apt build-dep -y --arch-only qemu
ARG QEMU_VERSION
RUN echo "QEMU_VERSION=${QEMU_VERSION:?QEMU_VERSION build arg must be set}"
RUN cd /tmp && \
git clone https://gitlab.com/qemu-project/qemu --depth 1 --single-branch
--branch "${QEMU_VERSION}" && \
cd qemu && ./configure --prefix=/opt/qemu && \
ninja -C build install && \
rm -rf /tmp/*
# now retrieve runtime dependencies (libs + loader)
RUN ldd /opt/qemu/bin/* | grep '=>' | sed -e 's/.*=>//' -e 's/(.*//' | sort -u
> /opt/qemu/libs.links
RUN find /lib/ld-linux* >> /opt/qemu/libs.links
RUN cat /opt/qemu/libs.links | xargs -n1 readlink -f > /opt/qemu/libs.realpath
# store them in /deps
RUN mkdir /deps && cp --parents $(cat /opt/qemu/libs.*) /deps/
################################################################################
FROM scratch
# FROM debian:13-slim
# in case you want a more complete container with a shell
# copy qemu and all associated artifacts (roms, ...)
COPY --from=build /opt/qemu /usr
COPY --from=build /deps /
# build with:
# podman build -f qemu.Dockerfile --build-arg QEMU_VERSION=v11.1.0 -t test
--squash-all
# run with:
# podman run -it --rm test qemu-system-aarch64 --version