diff --git a/ddk-parent/pom.xml b/ddk-parent/pom.xml
index fb098d150..88a2513fc 100644
--- a/ddk-parent/pom.xml
+++ b/ddk-parent/pom.xml
@@ -440,6 +440,21 @@
x86_64
+
+
+
+ linux
+ aarch64
+ unix
+
+
+ 64bit_linux_aarch64
+
+ linux
+ gtk
+ aarch64
+
+
macosx
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 000000000..0064f1899
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,9 @@
+FROM maven:3-eclipse-temurin-21-noble
+
+# Native libraries for SWT on GTK 3 and the JDK's AWT, a virtual display for the UI tests, and unzip for ./mvnw,
+# which otherwise downloads the .tar.gz that doesn't match its checksum.
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends libgtk-3-0t64 librsvg2-common libxtst6 unzip xvfb \
+ && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workspace
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 000000000..baa9094ed
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,26 @@
+# DDK Docker build environment
+
+A Linux image with Java, Maven, GTK and Xvfb, for running the full build and the UI tests headlessly on any machine with Docker (x86-64 or ARM64).
+
+Build the image from the repository root:
+
+```bash
+docker build --pull -t ddk-build docker
+```
+
+Run any build command from [AGENTS.md](../AGENTS.md#build-commands) in it, for example the full CI build, which already starts with `xvfb-run`:
+
+```bash
+docker run --rm --init \
+ --mount "type=bind,source=${PWD},target=/workspace" \
+ --mount "type=volume,source=ddk-m2,target=/root/.m2" \
+ ddk-build \
+
+```
+
+In PowerShell, use `$PWD.Path` for the source and backticks for the line breaks, and quote `-D` arguments (`'-DskipTests'`).
+
+- **Use a full clone, not a linked worktree:** a worktree's `.git` file points outside the mount, and Tycho's build qualifier then fails with `repository not found`.
+- **`--init` is required:** without it `xvfb-run` runs as PID 1 and can hang before starting Maven.
+- The `ddk-m2` volume keeps Maven and p2 downloads between runs; on a machine that builds both architectures, use one volume per architecture.
+- The container runs as root, so on a Linux host the build output in the checkout is owned by root.