Adam Pietrzycki

Dockerfile ONBUILD for customisable images

· 2 min read

Over the past couple of weeks, I've been working on building new base images for teams to use for their services. I designed these images to be small, yet include commonly used tools, and to ensure they remain patched and up-to-date.

One of those tools is Poetry, which recently had a major version release as I was working on the images. At first I included multiple versions of Poetry in the matrix. As I added more to the matrix, the number of images grew quickly.

  parallel:
    matrix:
      - python: ["3.13", "3.12", "3.11", "3.10", "3.9"]
      - poetry: ["1", "2"]

I was trying to work out if we could drop the extra Poetry versions to reduce complexity and CI jobs. Our DevEx team said the opposite was true. Because of breaking changes, we would likely need to support multiple minor versions of Poetry.

This is when I remembered reading about the ONBUILD instruction and wondered if we could use it to control the version of Poetry installed.

The ONBUILD instruction adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream Dockerfile. - docs

Base Image

FROM python:3.13-slim-bookworm

ENV POETRY_HOME=/opt/poetry \
    PIPX_HOME=/usr/local/pipx \
    PIPX_BIN_DIR=/usr/local/bin

RUN python -m pip install --no-cache-dir pipx \
    && python -m pipx ensurepath \
    && python --version \
    && rm -rf /root/.cache/pip /tmp/* /var/tmp/*

ARG LATEST_POETRY_VERSION=2.0.1 # pypi/poetry&versioning=semver
RUN pipx install poetry==${LATEST_POETRY_VERSION}

ONBUILD ARG POETRY_VERSION
ONBUILD RUN if [ -n "${POETRY_VERSION}" ]; then \
        pipx uninstall poetry && \
        pipx install poetry==${POETRY_VERSION}; \
    fi \
    && poetry --version

A few things to call out in this Dockerfile:

Default Image

FROM python-base:latest

CMD ["poetry", "--version"]

Running the image returns the Poetry version installed in the base image.

➜ docker run default
Poetry (version 2.0.1)

Custom Image

ARG POETRY_VERSION=1.8.4

FROM python-base:latest

CMD ["poetry", "--version"]

Running the image returns the Poetry version we specified in the ARG instruction.

➜ docker run custom
Poetry (version 1.8.4)