Q. CircleCIでPEP 668エラーが発生するようになった
いくつかのCircleCIを利用しているプロジェクトで、ある時期を境にPEP 668エラーが発生するようになった。 これはCircleCIが提供するDockerイメージのUbuntuが非自明的に上がることにより、意図せずPEP 668に従ったUbuntu 24.04になってしまったことによる。
エラーの発生
cimg/node:22.17.0
またはcimg/go:1.24.5
に更新されたjobで、pip install
実行時に次のエラーが出力されていた。
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`.
...
hint: See PEP 668 for the detailed specification.
なぜこのエラーが発生したのか
今回のケースではcimg/node
のマイナーバージョン更新で、基盤となるUbuntuのバージョンが大幅に変わっていた。
cimg/node:22.16
: Ubuntu 22.04.5 LTScimg/node:22.17
: Ubuntu 24.04.2 LTS
Ubuntu 24.04でPEP 668が採用されたため、システムグローバルな環境へのpip install
がブロックされるようになった。
またcimg/go
の場合は、パッチバージョンの更新によりUbuntuのバージョンが変わっていた。
cimg/go:1.24.4
: Ubuntu 22.04.5 LTScimg/go:1.24.5
: Ubuntu 24.04.2 LTS
各イメージで利用されているOSは次のページで確認できる。
- https://circleci.com/developer/images/image/cimg/node#image-tags
- https://circleci.com/developer/images/image/cimg/go#image-tags
Ubuntuの更新は四半期毎に行われる
cimg/node
やcimg/go
が利用するLinuxのバージョンは、親イメージであるcimg/base
から継承されている。
ベースイメージであるcimg/base
と、ベースイメージを継承した子イメージについてCircleCIは次のようなポリシーを採用している。
We build a new base image each month. However, we only update the base image used in child convenience images once per quarter. These updates are not retroactively applied to existing images, but will apply to new releases of the image after the change has been made.
出展:CircleCI Convenience Images Support Policy
ベースイメージ自体は月次で更新されるが、子イメージでは四半期ごとに利用されるベースイメージが更新される。つまり、パッチやマイナーに関わらず子イメージのOSバージョンがUbuntu 22.04.5からUbuntu 24.04.2のようなジャンプをする可能性があり、これをバージョンが推測することが困難である。
このポリシーによる問題は、今までにも事例が報告されている。
PEP 668について
PEP 668は、OSのパッケージマネージャー(apt
やyum
)とpip
の競合を避けるための仕様。Ubuntu 24.04から採用されている。
要するに、システムグローバルなpip install
がデフォルトでブロックされ、仮想環境(venv
)での管理が必須になった。これによりerror: externally-managed-environment
エラーが発生する。
出展:PEP 668 – Marking Python base environments as “externally managed”
解決方法
いくつかの対処法があるが、対象によってCircleCI OrbやOSのパッケージマネージャーを利用することが好ましいと思われる。
1. CircleCI Orbの使用
例えばAWS CLIのようにOrbが提供されているものであれば、Orbを利用することで解決する可能性が高い。
orbs:
aws-cli: circleci/aws-cli@5.4.1
jobs:
build:
docker:
- image: cimg/node:22.17.0
steps:
- checkout
- aws-cli/setup
参考:https://circleci.com/developer/ja/orbs/orb/circleci/aws-cli#commands-setup
2. パッケージマネージャーの使用
システムのパッケージマネージャーを使えば、PEP 668に従ったインストールが可能。
steps:
- run:
name: Install AWS CLI
command: |
apt install -y awscli
3. 仮想環境の使用(非推奨)
PEP 668に従う形で、Python仮想環境を作成してパッケージをインストールすることでも回避できるが、Pythonのプロダクトでも無ければ無駄が大きくなる可能性が高い。
steps:
- run:
name: Install AWS CLI in virtual environment
command: |
python3 -m venv venv
source venv/bin/activate
pip install awscli
4. 強制的な回避(非推奨)
--break-system-packages
フラグで強制的に回避できるが、システムの安定性を損なう可能性があるため推奨できない。
steps:
- run:
name: Force install AWS CLI (not recommended)
command: pip3 install --break-system-packages awscli
GitHub Actionsとの比較
ちなみに、GitHub Actionsでは同様の問題が発生した後に対応が取り込まれ、pipがデフォルト環境にパッケージをインストールできるようになっている。
出展: