4
4

ubuntu22.04を24.04に変更したら、`pip`のインストールで"externally-managed-environment"というエラーが発生した

Last updated at Posted at 2024-07-19

はじめに

以下は、VSCode Dev Containers用のDocker filesです。Ubuntu 22.04をベースイメージにしています。

Dockerfile.jammy
FROM ubuntu:22.04

# Install prerequisites
RUN set -x \
    && export DEBIAN_FRONTEND=noninteractive \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        gnupg2 \
        software-properties-common \
        language-pack-ja \
        tzdata \
        curl \
        lsb-release \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

# Set locale & timezone
RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE=ja_JP:ja \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo "Asia/Tokyo" > /etc/timezone

ENV LANG=ja_JP.UTF-8
ENV LC_ALL=ja_JP.UTF-8
ENV LC_CTYPE=ja_JP.UTF-8

# Install packages
RUN set -x \
    # 最新のPythonバージョンをインストールするために、deadsnakes PPAを追加
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        python3.12-dev \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

# Python / pip
RUN ln -s $(which python3.12) /usr/bin/python
RUN curl -sSL https://bootstrap.pypa.io/get-pip.py | python -
    

以下のコマンドは、ビルドしたイメージ上で実行しました。

root@43e0c835ea78:/# python --version
Python 3.12.4

root@43e0c835ea78:/# pip --version
pip 24.1.2 from /usr/local/lib/python3.12/dist-packages/pip (python 3.12)

何が起きたのか

最新のUbuntuバージョンを利用するために、ベースイメージをUbuntu 22.04からUbuntu 24.04に変更しました。しかし、docker buildx buildに失敗しました。
pipのインストールで失敗していました。

$ docker buildx build --file Dockerfile.noble .
[+] Building 13.9s (9/9) FINISHED                                                                                                                                                                 docker:default
 => [internal] load build definition from Dockerfile.noble                                                                                                                                                  0.0s
 => => transferring dockerfile: 1.14kB                                                                                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/ubuntu:24.04                                                                                                                                             0.0s
 => [internal] load .dockerignore                                                                                                                                                                           0.0s
 => => transferring context: 2B                                                                                                                                                                             0.0s
 => [1/6] FROM docker.io/library/ubuntu:24.04                                                                                                                                                               0.0s
 => CACHED [2/6] RUN set -x     && export DEBIAN_FRONTEND=noninteractive     && apt-get update     && apt-get install -y --no-install-recommends         gnupg2         software-properties-common          0.0s
 => CACHED [3/6] RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE=ja_JP:ja     && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime     && echo "Asia/Tokyo" > /etc/timezone                                  0.0s
 => CACHED [4/6] RUN set -x     && add-apt-repository ppa:deadsnakes/ppa     && apt-get update     && apt-get install -y --no-install-recommends         python3.12-dev     && apt-get -y clean     && rm   0.0s
 => CACHED [5/6] RUN ln -s $(which python3.12) /usr/bin/python                                                                                                                                              0.0s
 => ERROR [6/6] RUN curl -sSL https://bootstrap.pypa.io/get-pip.py | python -                                                                                                                              13.9s
------
 > [6/6] RUN curl -sSL https://bootstrap.pypa.io/get-pip.py | python -:
13.75 error: externally-managed-environment
13.75
13.75 × This environment is externally managed
13.75 ╰─> To install Python packages system-wide, try apt install
13.75     python3-xyz, where xyz is the package you are trying to
13.75     install.
13.75
13.75     If you wish to install a non-Debian-packaged Python package,
13.75     create a virtual environment using python3 -m venv path/to/venv.
13.75     Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
13.75     sure you have python3-full installed.
13.75
13.75     If you wish to install a non-Debian packaged Python application,
13.75     it may be easiest to use pipx install xyz, which will manage a
13.75     virtual environment for you. Make sure you have pipx installed.
13.75
13.75     See /usr/share/doc/python3.12/README.venv for more information.
13.75
13.75 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.
13.75 hint: See PEP 668 for the detailed specification.
------
Dockerfile.noble:38
--------------------
  36 |     # Python / pip
  37 |     RUN ln -s $(which python3.12) /usr/bin/python
  38 | >>> RUN curl -sSL https://bootstrap.pypa.io/get-pip.py | python -
  39 |
  40 |
--------------------
ERROR: failed to solve: process "/bin/sh -c curl -sSL https://bootstrap.pypa.io/get-pip.py | python -" did not complete successfully: exit code: 1

以下のコマンドは、エラーが起きたRUN curl -sSL https://bootstrap.pypa.io/get-pip.py | python -をコメントアウトして作成したイメージ上で実行しました。

root@c89918743e60:/# python --version
Python 3.12.3

pipのインストールに失敗した原因

Ubuntu 24.04のpythonパッケージでは、PEP668に対応しているためです。

PEP668については、以下のサイトが参考になりました。

提案されているのは、OS側のpython3のディレクトリにEXTERNALLY-MANAGEDファイルをおいたら、そこはpython用のモジュール管理コマンドの影響から保護してね!という内容です。

Ubunutu 24.04では、/usr/lib/python3.12EXTERNALLY-MANAGEDというファイルが存在していることを確認しました。

root@c89918743e60:/# python -c 'import sysconfig; print(sysconfig.get_path("stdlib"))'
/usr/lib/python3.12

root@c89918743e60:/# ls /usr/lib/python3.12/EXTERNALLY-MANAGED -l
-rw-r--r-- 1 root root 645  4月 10 14:33 /usr/lib/python3.12/EXTERNALLY-MANAGED

root@c89918743e60:/# ls /usr/lib/python3.12/EXTERNALLY-MANAGED -l
-rw-r--r-- 1 root root 645  4月 10 14:33 /usr/lib/python3.12/EXTERNALLY-MANAGED

root@c89918743e60:/# cat /usr/lib/python3.12/EXTERNALLY-MANAGED
[externally-managed]
Error=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.12/README.venv for more information.

また、Ubunutu 22.04では、/usr/lib/python3.12EXTERNALLY-MANAGEDというファイルは存在しないことを確認できました。

解決方法

メッセージにある通り、pipxパッケージをインストールして、pipでなくpipxを利用するようにしました。

FROM ubuntu:24.04

# Install prerequisites
RUN set -x \
    && export DEBIAN_FRONTEND=noninteractive \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        gnupg2 \
        software-properties-common \
        language-pack-ja \
        tzdata \
        curl \
        lsb-release \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

# Set locale & timezone
RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE=ja_JP:ja \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo "Asia/Tokyo" > /etc/timezone

ENV LANG=ja_JP.UTF-8
ENV LC_ALL=ja_JP.UTF-8
ENV LC_CTYPE=ja_JP.UTF-8

# Install packages
RUN set -x \
    # 最新のPythonバージョンをインストールするために、deadsnakes PPAを追加
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        python3.12-dev \
        pipx \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

# Python / pipx
RUN ln -s $(which python3.12) /usr/bin/python
RUN pipx ensurepath

    

参考サイト

4
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4