diff --git a/documentation/tools/build-docs b/documentation/tools/build-docs
new file mode 100755
index 0000000000000000000000000000000000000000..2fe8aff3a9834e4f5015e04d64b7462190278004
--- /dev/null
+++ b/documentation/tools/build-docs
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+#
+# Build the documentation in a container built by build-docs-container.
+#
+# Usage:
+#
+#   ./documentation/tools/build-docs <image> [<command>]
+#
+# Where <image> is one of the keys in
+# documentation/tools/build-docs-container's DEPS_KEYS_YQ.
+# And <command> an optional command to run, default being to run "make publish".
+#
+# E.g.:
+#
+#   ./documentation/tools/build-docs ubuntu-24-04
+
+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
+CONTAINERCMD=${CONTAINERCMD:-docker}
+
+DOCS_DIR="$SCRIPT_DIR/../.."
+
+main ()
+{
+  local image="$1"
+  shift
+  local command="${*:-make -C documentation publish}"
+
+  if [ "$CONTAINERCMD" = "docker" ]; then
+    EXTRA_ARGS_RUN="--user $(id -u):$(id -g)"
+  elif [ "$CONTAINERCMD" = "podman" ]; then
+    # we need net access to fetch bitbake terms
+    EXTRA_ARGS_RUN="\
+      --cap-add=NET_RAW \
+      --userns=keep-id"
+  fi
+
+  $CONTAINERCMD run \
+    --rm --interactive --tty \
+    --volume "$DOCS_DIR:/docs:rw" \
+    --workdir "/docs" \
+    $EXTRA_ARGS_RUN \
+    "yocto-docs-$image" \
+    $command
+}
+
+set -eu -o pipefail
+
+main "$@"
diff --git a/documentation/tools/build-docs-container b/documentation/tools/build-docs-container
new file mode 100755
index 0000000000000000000000000000000000000000..8cfe0f7aa75bf5fcfbbc0e838d66e0ef10f20696
--- /dev/null
+++ b/documentation/tools/build-docs-container
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+#
+# Build a container ready to build the documentation be reading the dependencies
+# listed in poky.yaml.in.
+#
+# Usage:
+#
+#   ./documentation/tools/build-docs-container <image>
+#
+# Where <image> is one of the keys in DEPS_KEYS_YQ. E.g.:
+#
+#   ./documentation/tools/build-docs-container ubuntu-24-04
+
+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
+CONTAINERCMD=${CONTAINERCMD:-docker}
+
+# Keys used by yq to get the dependencies from poky.yaml.in
+declare -A DEPS_KEYS_YQ=(
+  [ubuntu-24-04]=".UBUNTU_DEBIAN_HOST_PACKAGES_DOC .UBUNTU_DEBIAN_HOST_PACKAGES_DOC_PDF"
+  [debian-12]=".UBUNTU_DEBIAN_HOST_PACKAGES_DOC .UBUNTU_DEBIAN_HOST_PACKAGES_DOC_PDF"
+)
+
+main ()
+{
+  local image="$1"
+
+  for cmd in $CONTAINERCMD yq; do
+    if ! which "$cmd" >/dev/null 2>&1; then
+      echo "The $cmd command was not found. Make sure you have $cmd installed."
+      exit 1
+    fi
+  done
+
+  local dockername="Dockerfile.$image"
+
+  # Put all the dependencies in the deps variable
+  for dep_key in ${DEPS_KEYS_YQ[$image]}; do
+    deps="$deps $(yq --raw-output "$dep_key" "$SCRIPT_DIR/../poky.yaml.in")"
+  done
+
+  ( cd "$SCRIPT_DIR/dockerfiles" \
+    && $CONTAINERCMD build \
+    --tag "yocto-docs-$image:latest" \
+    --file "$dockername" \
+    --build-arg DEPS="$deps" \
+    . )
+}
+
+set -e -o pipefail
+
+main "$@"
diff --git a/documentation/tools/dockerfiles/Dockerfile.debian-12 b/documentation/tools/dockerfiles/Dockerfile.debian-12
new file mode 100644
index 0000000000000000000000000000000000000000..18c9c45c3ccfc5d90a09057d874512c6b9826611
--- /dev/null
+++ b/documentation/tools/dockerfiles/Dockerfile.debian-12
@@ -0,0 +1,17 @@
+FROM debian:12
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+ARG DEPS
+ENV DEPS=${DEPS}
+
+RUN apt-get update \
+ && apt-get --yes --fix-broken upgrade \
+ && apt-get --yes --no-install-recommends install \
+    ${DEPS} \
+ && apt-get --yes autoremove \
+ && apt-get clean
+
+RUN LANG="en_US.UTF-8" locale-gen
+
+RUN git config --global --add safe.directory /docs
diff --git a/documentation/tools/dockerfiles/Dockerfile.ubuntu-24-04 b/documentation/tools/dockerfiles/Dockerfile.ubuntu-24-04
new file mode 100644
index 0000000000000000000000000000000000000000..6ac384c4f242b508027a92d2acad490da41dc374
--- /dev/null
+++ b/documentation/tools/dockerfiles/Dockerfile.ubuntu-24-04
@@ -0,0 +1,17 @@
+FROM ubuntu:24.04
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+ARG DEPS
+ENV DEPS=${DEPS}
+
+RUN apt-get update \
+ && apt-get --yes --fix-broken upgrade \
+ && apt-get --yes --no-install-recommends install \
+    ${DEPS} \
+ && apt-get --yes autoremove \
+ && apt-get clean
+
+RUN LANG="en_US.UTF-8" locale-gen
+
+RUN git config --global --add safe.directory /docs
