diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
new file mode 100644
index 000000000..a3445fc5e
--- /dev/null
+++ b/.github/workflows/docker.yml
@@ -0,0 +1,53 @@
+---
+name: Docker Workflow
+on:
+ push:
+ branches: [master]
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry ${{ env.REGISTRY }}
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract Docker metadata
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ flavor: latest=true
+ tags: type=ref,event=push
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+
+ - name: Setup context
+ run: make -C docker setup
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v5
+ with:
+ platforms: linux/amd64
+ context: docker
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
diff --git a/docker/.gitignore b/docker/.gitignore
new file mode 100644
index 000000000..4414fc1e2
--- /dev/null
+++ b/docker/.gitignore
@@ -0,0 +1 @@
+requirements.txt
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 000000000..7b686e7a3
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Copyright (C) 2024 Randolph Sapp
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see .
+
+FROM debian:stable-slim
+
+RUN apt-get update \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y \
+ --no-install-recommends \
+ dumb-init \
+ git \
+ gosu \
+ make \
+ python3-pip \
+ ripgrep \
+ zip \
+ && echo "**** create abc user and make our folders ****" \
+ && useradd -u 1000 -U -d /config -s /bin/false abc \
+ && usermod -G users abc \
+ && mkdir /build && chown abc:abc /build \
+ && mkdir /config && chown abc:abc /config \
+ && echo "**** cleanup ****" \
+ && apt-get autoremove \
+ && apt-get clean \
+ && rm -rf \
+ /tmp/* \
+ /var/cache/debconf/*-old \
+ /var/lib/apt/lists/* \
+ /var/lib/dpkg/status-old \
+ /var/lib/sgml-base/supercatalog.old \
+ /var/log/apt/term.log \
+ /var/tmp/*
+
+RUN --mount=type=bind,source=requirements.txt,target=/tmp/requirements.txt \
+ python3 -m pip install -r /tmp/requirements.txt --no-cache-dir \
+ --break-system-packages
+
+COPY root/ /
+
+WORKDIR /build
+VOLUME /build
+
+ENTRYPOINT ["/init"]
+CMD ["/bin/bash"]
diff --git a/docker/Makefile b/docker/Makefile
new file mode 100644
index 000000000..14a0a6a78
--- /dev/null
+++ b/docker/Makefile
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Copyright (C) 2024 Randolph Sapp
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see .
+
+ifeq ($(CONTAINER_TOOL),)
+ $(info CONTAINER_TOOL unset, checking if docker is present...)
+ ifneq ($(shell which docker 2> /dev/null),)
+ $(info Using docker for build...)
+ CONTAINER_TOOL := docker
+ else ifneq ($(shell which podman 2> /dev/null),)
+ $(info Using podman for build...)
+ CONTAINER_TOOL := podman
+ endif
+endif
+
+.PHONY: all setup
+all: Dockerfile setup
+ $(CONTAINER_TOOL) build . -t texasinstruments/processor-sdk-doc \
+ $(BUILD_ARGS)
+
+setup: requirements.txt
+
+requirements.txt:
+ cp -ar ../requirements.txt .
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 000000000..cdad8636f
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,33 @@
+# psdk-doc-docker
+
+A simple docker container to build
+[processor-sdk-doc](https://github.com/TexasInstruments/processor-sdk-doc).
+
+
+## Why
+
+Preempting incompatibility as that repos is still using some deprecated sphinx
+calls. Sphinx has some dependency resolution issues when mixing system and local
+python library installations that causes unusual artifacts. This guarantees a
+reproducible build output.
+
+
+## Building
+
+You need podman or docker for building. If either one of those is already
+installed then just run `make`.
+
+
+## Usage
+
+New tooling has unified the invocation of Podman and Docker by fetching the
+owner of the build directory and remapping an internal user to satisfy build
+requirements. It will fail if the directory owner is in a reserved uid/gid
+region.
+
+After starting the container with your preferred container tool, follow the
+instructions for building the documentation as usual.
+
+```bash
+docker run -it --rm -v "$PWD":/build ghcr.io/texasinstruments/processor-sdk-doc
+```
diff --git a/docker/root/init b/docker/root/init
new file mode 100755
index 000000000..d0e48092c
--- /dev/null
+++ b/docker/root/init
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+# SPDX-License-Identifier: GPL-2.0
+
+# Copyright (C) 2024 Randolph Sapp
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see .
+
+get_attribs() {
+ local file_stats file_to_test useful_attribs
+ if file_to_test=$(realpath "$1") && [[ $2 =~ ^[0-9]+$ ]] ; then
+ useful_attribs=$(stat "$file_to_test" -t)
+ read -r -a file_stats <<< "${useful_attribs#"$file_to_test"}"
+ echo "${file_stats["$2"]}"
+ else
+ return 1
+ fi
+}
+
+get_build_uid() {
+ get_attribs /build 3
+}
+
+get_build_gid() {
+ get_attribs /build 4
+}
+
+if NEW_GID=$(get_build_gid) && NEW_UID=$(get_build_uid); then
+ # bypass everything if podman is remapping the id to root
+ if [ "${NEW_UID}" == "0" ]; then
+ if [ "$(id -u)" == "0" ]; then
+ exec dumb-init -- "$@"
+ else
+ echo "Unable to resolve ns mapping!"
+ fi
+ fi
+
+ # change the uid and gid of abc otherwise
+ [ "$NEW_GID" != "$(id -g abc)" ] && groupmod -g "${NEW_GID}" abc
+ [ "$NEW_UID" != "$(id -u abc)" ] && usermod -u "${NEW_UID}" abc
+else
+ echo "Not able to detect UID/GID for remapping!"
+fi
+
+if [ "$(id -u)" == "$(id -u abc)" ]; then
+ exec dumb-init -- "$@"
+else
+ exec dumb-init -- gosu abc "$@"
+fi
diff --git a/requirements.txt b/requirements.txt
index 2a2034039..0b428da2c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -21,3 +21,4 @@ sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
urllib3==2.2.1
+rstcheck==3.3.1