diff --git a/README.md b/README.md
index 9cc72c9..cacad1d 100644
--- a/README.md
+++ b/README.md
@@ -83,13 +83,17 @@ jobs:
The [Open Cyphal toxic
container](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic)
-is based on Ubuntu and provides all modern Python3 distributions, pip, tox, and nox. It can be used to develop, test, build, and release Python projects like [nunavut](https://github.com/OpenCyphal/nunavut), [pydsdl](https://github.com/OpenCyphal/pydsdl), and [pycyphal](https://github.com/OpenCyphal/pycyphal).
+is based on Ubuntu and provides supported Python 3 interpreters, pip, tox, and nox. It can be used to develop, test, build, and release Python projects like [nunavut](https://github.com/OpenCyphal/nunavut), [pydsdl](https://github.com/OpenCyphal/pydsdl), and [pycyphal](https://github.com/OpenCyphal/pycyphal).
+
+`tx26.4.1` uses Ubuntu 26.04 LTS with Python 3.14 as the default interpreter.
+See [toxic/README.md](toxic/README.md) for usage and build instructions.
#### Supported Versions
| tag | Base Python | Python Versions | Tox | Nox | pip | Platforms | Other Utilities |
|----------|-------------|-----------------|-----|-----|-----|-----------|-----------------|
-| [tx22.4.3](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic) | 3.11 | 3.8, 3.9, 3.10, 3.11, 3.12 3.13 | 4.13.0 | 2023.4.22 | 20.0.2 |
| |
+| [tx26.4.1](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic) | 3.14 | 3.11, 3.12, 3.13, 3.14, 3.15 | 4.67.1 | 2026.8.17 | 25.1.1 | | |
+| [tx22.4.3](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic) | 3.11 | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 | 4.13.0 | 2023.4.22 | 20.0.2 | | |
| [tx22.4.2](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic) | 3.10 | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 4.13.0 | 2023.4.22 | 20.0.2 | | |
| [tx22.4.1](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic) | 3.8 | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 4.4.5 | 2023.4.22 | 20.0.2 | | |
| [tx20.4.1](https://github.com/OpenCyphal/docker_toolchains/pkgs/container/toxic) | 3.8 | 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 4.4.5 | (not available) | 20.0.2 | | |
@@ -101,7 +105,7 @@ You can use this in your workflow yaml like this:
jobs:
my-job:
runs-on: ubuntu-latest
- container: ghcr.io/opencyphal/toxic:tx20.4.2
+ container: ghcr.io/opencyphal/toxic:tx26.4.1
```
---------------------------
diff --git a/toxic/Dockerfile b/toxic/Dockerfile
index 7ea40ce..a61d5ba 100644
--- a/toxic/Dockerfile
+++ b/toxic/Dockerfile
@@ -1,7 +1,7 @@
#
-# Builds the toxic/ubuntu-22.04 toolchain container.
+# Builds the toxic/ubuntu-26.04 toolchain container.
#
-FROM ubuntu:22.04 AS base
+FROM ubuntu:26.04 AS base
LABEL org.opencontainers.image.source=https://github.com/OpenCyphal/docker_toolchains
LABEL org.opencontainers.image.description="Provides a consistent build and test environment for development, continuous-integration, and test automation of OpenCyphal Python based projects."
@@ -14,6 +14,8 @@ WORKDIR /repo
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
+ENV PIPX_HOME=/opt/pipx
+ENV PIPX_BIN_DIR=/usr/local/bin
# +---------------------------------------------------------------------------+
# | UBUNTU PROVISIONING
@@ -28,13 +30,13 @@ ADD post-provision.sh ./post-provision.sh
RUN ./pre-provision.sh
RUN ./provision.sh
-RUN ./provision-python.sh 3.8 6 distutils
-RUN ./provision-python.sh 3.9 5 distutils
-RUN ./provision-python.sh 3.10 4 distutils
-RUN ./provision-python.sh 3.11 3 distutils
-RUN ./provision-python.sh 3.12 1 distutils
-RUN ./provision-python.sh 3.13 2
-RUN update-alternatives --set python3 /usr/bin/python3.11
+RUN ./provision-python.sh 3.11 distutils
+RUN ./provision-python.sh 3.12
+RUN ./provision-python.sh 3.13
+RUN ./provision-python.sh 3.14
+RUN ./provision-python.sh 3.15
+# Keep Ubuntu's system interpreter as the default for pip and distro utilities.
+RUN python3 -c 'import sys; assert sys.version_info[:2] == (3, 14)'
RUN ./provision-pip.sh
RUN ./post-provision.sh
diff --git a/toxic/README.md b/toxic/README.md
index 0b0ab62..5b55338 100644
--- a/toxic/README.md
+++ b/toxic/README.md
@@ -3,14 +3,23 @@
The `opencyphal/toxic` docker image provides a consistent build and test environment
for development, continuous-integration, and test automation of Python based projects.
+## Python support
+
+Based on Ubuntu 26.04 LTS, the image supports Python **3.11–3.15** on
+`linux/amd64` and `linux/arm64`. The default `python3`, `pip`, and `pip3` use
+**Python 3.14**, Ubuntu 26.04's [default Python version](https://packages.ubuntu.com/resolute/python3).
+
+Each interpreter includes `venv`; use versioned commands such as `python3.15 -m venv .venv`
+to create project environments. tox and nox are installed through pipx and available on `PATH`.
+
## Official Release
To release a new build of this container simply create a [new github release](https://github.com/OpenCyphal/docker_toolchains/releases/new)
that starts with `tx`, uses the Ubuntu major and minor version, and uses an monotonically increasing "patch" version.
-For example `tx22.4.1`will cause the Github workflow to rebuild and push the `opencyphal/toxic` container with the
-tag `tx22.4.1`.
+For example `tx26.4.1` will cause the Github workflow to rebuild and push the `opencyphal/toxic` container with the
+tag `tx26.4.1`.
-When submitting a pull-request, include `#tx` in the commit message to trigger the pull-request CI.
+When submitting a pull-request, include `#tx` in the pull-request title to trigger the pull-request CI.
***PLEASE UPDATE THE TOP-LEVEL README.md FOR EACH NEW RELEASE***
@@ -53,7 +62,7 @@ docker buildx use cyphalbuild
... then build the container:
```bash
-docker buildx build --platform linux/amd64,linux/arm64 --load -t ghcr.io/opencyphal/toxic:tx22.4.x .
+docker buildx build --platform linux/amd64,linux/arm64 --load -t ghcr.io/opencyphal/toxic:tx26.4.x .
```
(where x is the next version number for the container)
@@ -61,13 +70,13 @@ docker buildx build --platform linux/amd64,linux/arm64 --load -t ghcr.io/opencyp
After this completes you'll see your image using the classic `docker images` command or the newer `buildx imagetools` command to inspect the multi-architecture manifest:
```
-docker buildx imagetools inspect ghcr.io/opencyphal/toxic:tx22.4.x
+docker buildx imagetools inspect ghcr.io/opencyphal/toxic:tx26.4.x
```
Now you can login to the container to test it out:
```bash
-docker run --rm -it -v ${PWD}:/repo ghcr.io/opencyphal/toxic:tx22.4.x
+docker run --rm -it -v ${PWD}:/repo ghcr.io/opencyphal/toxic:tx26.4.x
```
### Push
@@ -75,7 +84,7 @@ docker run --rm -it -v ${PWD}:/repo ghcr.io/opencyphal/toxic:tx22.4.x
As with load, you need to re-build with a `--push` argument but you'll be using the cache so the build should be a no-op:
```bash
-docker buildx build --platform linux/amd64,linux/arm64 --push -t ghcr.io/opencyphal/toxic:tx22.4.x .
+docker buildx build --platform linux/amd64,linux/arm64 --push -t ghcr.io/opencyphal/toxic:tx26.4.x .
```
## More on Multi-Platform Builders
diff --git a/toxic/provision-pip.sh b/toxic/provision-pip.sh
index 3b8f000..0996d6f 100755
--- a/toxic/provision-pip.sh
+++ b/toxic/provision-pip.sh
@@ -21,7 +21,13 @@ set -o pipefail
# +----------------------------------------------------------+
export DEBIAN_FRONTEND=noninteractive
-apt-get -y install python3-pip
+apt-get -y install python3-pip pipx
-pip3 install tox
-pip3 install nox
+# Ubuntu's system Python is externally managed. Keep CLI tools in isolated
+# environments while exposing their entry points through PIPX_BIN_DIR.
+pipx install --python /usr/bin/python3.14 tox
+pipx install --python /usr/bin/python3.14 nox
+
+pip3 --version
+tox --version
+nox --version
diff --git a/toxic/provision-python.sh b/toxic/provision-python.sh
index 73fbe98..31e4ac9 100755
--- a/toxic/provision-python.sh
+++ b/toxic/provision-python.sh
@@ -15,10 +15,8 @@ set -o pipefail
# +----------------------------------------------------------+
export DEBIAN_FRONTEND=noninteractive
-apt-get -y install python$1
+apt-get -y install "python${1}" "python${1}-venv"
-if [[ $3 == distutils ]]; then
- apt-get -y install python$1-distutils
+if [[ ${2:-} == distutils ]]; then
+ apt-get -y install "python${1}-distutils"
fi
-
-update-alternatives --install /usr/bin/python3 python3 /usr/bin/python$1 $2