Docker pip error: externally-managed-environment in a Dockerfile (tested)

pip install in a Dockerfile fails with error: externally-managed-environment when the image's Python comes from Debian or Ubuntu packages. The official python: images don't have this. Below the error is reproduced and four fixes are built and run.

1. Reproduce: five Dockerfiles

d1 is the failing pattern: a Debian base image, Python from apt, then pip install. d2-d5 are the four ways out:

# ---- d1/Dockerfile
FROM debian:trixie-slim
RUN apt-get update -qq && apt-get install -y -qq python3-pip >/dev/null
RUN pip install six
# ---- d2/Dockerfile
FROM python:3-slim
RUN pip install -q --root-user-action=ignore six && python -c "import six; print(\"six\", six.__version__)"
# ---- d3/Dockerfile
FROM debian:trixie-slim
RUN apt-get update -qq && apt-get install -y -qq python3-venv >/dev/null
RUN python3 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install -q six && python -c "import six; print(\"six\", six.__version__)"
# ---- d4/Dockerfile
FROM debian:trixie-slim
RUN apt-get update -qq && apt-get install -y -qq python3-pip >/dev/null
RUN pip install -q --break-system-packages six && python3 -c "import six; print(\"six\", six.__version__)"
# ---- d5/Dockerfile
FROM debian:trixie-slim
RUN apt-get update -qq && apt-get install -y -qq python3-six >/dev/null
RUN python3 -c "import six; print(\"six\", six.__version__)" && ls /usr/lib/python3*/EXTERNALLY-MANAGED

run.sh builds each one and prints only what the RUN steps wrote:

#!/bin/sh
# build each Dockerfile; print only what the RUN steps wrote, plus the build result
for d in d1 d2 d3 d4 d5; do
  echo "== $d"
  docker build --no-cache --progress=plain -t forever-em410:x $d > build.log 2>&1 \
    && echo "(build OK)" || echo "(build FAILED)"
  grep -E '^#[0-9]+ [0-9]+\.[0-9]+ ' build.log | sed -E 's/^#[0-9]+ [0-9.]+ //' \
    | grep -vE 'debconf|^$|dpkg-preconfigure|^Selecting|^Preparing|^Unpacking|^Setting up|^Processing|^\(Reading'
done

Output (Docker, debian:trixie-slim with its Python 3.13, and python:3-slim):

== d1
(build FAILED)
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.
    
    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.
    
    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.
    
    See /usr/share/doc/python3.13/README.venv for more information.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
== d2
(build OK)
six 1.17.0
== d3
(build OK)
six 1.17.0
== d4
(build OK)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
six 1.17.0
== d5
(build OK)
six 1.17.0
/usr/lib/python3.13/EXTERNALLY-MANAGED

2. Why it happens only on some images

Debian (12 and later) and Ubuntu (23.04 and later) ship a marker file /usr/lib/python3.X/EXTERNALLY-MANAGED (d5 lists it on Debian trixie). When pip sees it, it refuses to install into the system Python so it can't overwrite files that apt owns (PEP 668). Being root inside a container does not change that. The official python:* images build their own Python in /usr/local and have no marker: in python:3-slim (Python 3.15.1 here) find / -name EXTERNALLY-MANAGED found nothing, and d2 installed normally.

3. Which fix to use

If the venv build later fails with ModuleNotFoundError, the CMD is probably running the system Python instead of the venv: see Docker Python ModuleNotFoundError. Outside Docker: pip error: externally-managed-environment.

Frequently asked questions

Why does pip say externally-managed-environment in Docker?

The base image is Debian 12+ or Ubuntu 23.04+ with Python from apt, which ships an EXTERNALLY-MANAGED marker file. pip refuses to install into that system Python, even as root.

Do the official python Docker images have externally-managed-environment?

No. python:3-slim has no EXTERNALLY-MANAGED file and pip install works directly.

Is --break-system-packages safe in a Dockerfile?

It works and is common in throwaway images, but pip can then overwrite packages apt installed. A venv on PATH avoids the risk.

Written with AI assistance. Measured on 2026-10-23 with Docker, debian:trixie-slim (Python 3.13) and python:3-slim (Python 3.15.1). The scripts ran verbatim and the output was pasted unedited. PlainTables is our extension; Docker and Python are free.