docker build: No module named 'pkg_resources' (tested Dockerfile fix)

docker build fails at a RUN pip install step with ModuleNotFoundError: No module named 'pkg_resources' during "Getting requirements to build wheel". Tested fix: a setuptools<81 constraint file passed with both PIP_CONSTRAINT and PIP_BUILD_CONSTRAINT, because which one pip uses depends on its version.

1. The error in docker build

Our test package was cx_Oracle 8.3.0. It has no wheel for Python 3.11, so pip builds it from the sdist, and its setup.py imports pkg_resources. This Dockerfile:

FROM python:3.11-alpine
RUN apk add --no-cache build-base
RUN pip install --no-cache-dir cx_Oracle==8.3.0
$ docker build --progress=plain --no-cache .
#6 [3/3] RUN pip install --no-cache-dir cx_Oracle==8.3.0
#6 2.523 Collecting cx_Oracle==8.3.0
#6 2.553   Downloading cx_Oracle-8.3.0.tar.gz (363 kB)
#6 2.579      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 363.9/363.9 kB 15.6 MB/s eta 0:00:00
#6 2.658   Installing build dependencies: started
#6 4.652   Installing build dependencies: finished with status 'done'
#6 4.653   Getting requirements to build wheel: started
[... trimmed ...]
#6 4.859       ModuleNotFoundError: No module named 'pkg_resources'
[... trimmed ...]
#6 ERROR: process "/bin/sh -c pip install --no-cache-dir cx_Oracle==8.3.0" did not complete successfully: exit code: 1

pip builds the sdist in an isolated build env (/tmp/pip-build-env-...) with the newest setuptools, and setuptools 82.0.0 removed pkg_resources. The image itself has setuptools 79.0.1, and import pkg_resources works in it, but the build env does not use the image's setuptools, so pinning setuptools in the image does not help.

2. Check your pip version first

The python:3.11-alpine image we pulled ships pip 24.0. Which environment variable reaches the build env depends on the pip version:

3. Fix: set both variables (tested on pip 24.0 and 26.2.2)

FROM python:3.11-alpine
RUN apk add --no-cache build-base
RUN echo "setuptools<81" > /tmp/constraints.txt
ENV PIP_CONSTRAINT=/tmp/constraints.txt PIP_BUILD_CONSTRAINT=/tmp/constraints.txt
RUN pip --version && pip install --no-cache-dir cx_Oracle==8.3.0
RUN python -c "import cx_Oracle; print(cx_Oracle.version)"

This built and printed 8.3.0 on the image's pip 24.0. We also tested it with RUN pip install --no-cache-dir --upgrade pip added before the install:

#8 0.655 pip 26.2.2 from /usr/local/lib/python3.11/site-packages/pip (python 3.11)
[... trimmed ...]
#8 23.18 Successfully installed cx_Oracle-8.3.0
[... trimmed ...]
#9 0.597 8.3.0

Remember that PIP_CONSTRAINT also stops anything else in that image from installing setuptools 81 or newer at runtime. If you only want the build-time cap, upgrade pip and set only PIP_BUILD_CONSTRAINT (we tested that too: pip 26.2.2, cx_Oracle installed, import printed 8.3.0). On Alpine you also need build-base, or gcc fails after the pkg_resources step is fixed. For cx_Oracle itself, the long-term fix is oracledb.

Same root cause elsewhere: No module named 'pkg_resources' (general fix) · pipenv · Poetry · uv.

Frequently asked questions

Why doesn't pip install setuptools<81 in my Dockerfile fix it?

pip builds sdists in a separate isolated build env that gets the newest setuptools, not the image's. Use a constraint file via PIP_CONSTRAINT (older pip, e.g. 24.0) or PIP_BUILD_CONSTRAINT (pip 26.2.2).

Why does PIP_BUILD_CONSTRAINT not work in my Docker image?

Your image's pip may be too old. python:3.11-alpine shipped pip 24.0, which ignored it. Either set PIP_CONSTRAINT as well or upgrade pip first.

Written with AI assistance. Measured on 2026-10-24 on Linux with Docker BuildKit, python:3.11-alpine (pip 24.0, then upgraded to pip 26.2.2), installing cx_Oracle 8.3.0 (sdist) with --no-cache. Output pasted unedited except marked trims. PlainTables is our extension; Docker and pip are free.