MJUN Tech Note

python-build-standaloneとDockerによるポータブルなPython環境の構築

こんにちは。今回は、Linux, macOS, Windows/x86,arm に対応した ポータブルなPython環境を展開可能なpython-build-standaloneについて紹介します。

GitHub - indygreg/python-build-standalone: Produce redistributable builds of Python
Produce redistributable builds of Python. Contribute to indygreg/python-build-standalone development by creating an account on GitHub.
GitHub - indygreg/python-build-standalone: Produce redistributable builds of Python favicon https://github.com/indygreg/python-build-standalone
GitHub - indygreg/python-build-standalone: Produce redistributable builds of Python
Python Standalone Builds — python-build-standalone documentation
Python Standalone Builds — python-build-standalone  documentation favicon https://gregoryszorc.com/docs/python-build-standalone/main/

概要

Githubで公開されているリポジトリであるpython-build-standaloneでは、 各OS, CPUアーキテクチャに対応したビルド済みのPythonが配布されています。 配布されているPythonはpipを同梱済みなので、ダウンロード後すぐにPython環境を 使い始めることができます。 また、ここで提供されているPythonは、最近注目されているパッケージマネージャのRyeやmiseでも 用いられており、柔軟なPython環境の構築に役立っています。

配布されているPythonはライセンスの関係で、自前でビルドしたものと挙動が異なる場合がありますが、 ほとんどの動作において問題はありません。詳しくは以下の記事に書かれています。

Ryeに見る自己完結型Pythonとライセンスの話 - techtekt
目次 目次 はじめに 検証環境 pyenv + Poetryのインストールとプロジェクト作成 pyenvのインストール Poetryのインストール プロジェクト作成 Ryeのインストールとプロジェクト作成 インストール プロジェクト作成 pyenv環境とRye環境のPythonの挙動の違い readlineモジュール なぜRyeのPythonはlibeditを使用するのか pyenvよるPythonのインストール RyeによるPythonのインストール ライセンスの問題 ユーザへの影響 まとめ はじめに Pythonの開発において、pyenvによるバージョンの切り替えと、Poetryによるプロ…
Ryeに見る自己完結型Pythonとライセンスの話 - techtekt favicon https://techtekt.persol-career.co.jp/entry/tech/240523_01
Ryeに見る自己完結型Pythonとライセンスの話 - techtekt

提供されているPython

python-build-standaloneでは、様々なOSとCPUアーキテクチャに対応したPythonのビルド済みバイナリが提供されています。 以下のGithubのReleaseページから入手することができます。

Releases · indygreg/python-build-standalone
Produce redistributable builds of Python. Contribute to indygreg/python-build-standalone development by creating an account on GitHub.
Releases · indygreg/python-build-standalone favicon https://github.com/indygreg/python-build-standalone/releases
Releases · indygreg/python-build-standalone

入手できるバイナリの命名規則は以下の順になっています。

cpython-(Pythonバージョン)+(releaseのタイムスタンプ)-(アーキテクチャ)-(ビルド設定)-(同梱内容)

それぞれの項目は以下のようになっています。

releaseのタイムスタンプ

GitHubのTagとして設定されている、Releaseを公開した日付を入れます。 最新のReleaseの日付は以下のGitHub APIから確認することができます。

raw.githubusercontent.com
raw.githubusercontent.com favicon https://raw.githubusercontent.com/indygreg/python-build-standalone/latest-release/latest-release.json

アーキテクチャ

項目内容
aarch64-apple-darwinmacOS ARM CPU。M1, M2, M3 など。
x86_64-apple-darwinmacOS Intel CPU
i686-pc-windows-msvcWindows 32 ビット Intel/AMD CPU
x86_64-pc-windows-msvcWindows 64 ビット Intel/AMD CPU
*-windows-msvc-sharedWindows の Python 標準ビルド。Python とエクステンションの DLL がある。公式 Windows 用 Python と同様の動作。
*-windows-msvc-static静的リンクの Python ビルド。非常に脆弱で既知の互換性問題あり。包括的なテストカバレッジがあり、使用ケースで動作確認済みの場合以外は非推奨。
x86_64-unknown-linux-gnuLinux 64 ビット Intel/AMD CPU、GNU libc とリンク。
x86_64-unknown-linux-muslLinux 64 ビット Intel/AMD CPU、musl libc とリンク。静的バイナリで共有ライブラリ依存なし。Python の.so拡張を読み込めない。
aarch64-unknown-linux-*Linux ARM64 CPU 向け。AWS Graviton EC2 インスタンスなどに適用。多くの Linux ARM デバイスもaarch64
i686-unknown-linux-*Linux 32 ビット Intel/AMD CPU。
x86_64_v2-*2008 年以降の Nehalem 以降の 64 ビット Intel/AMD CPU 向け。SSE3、SSE4 など搭載。古い CPU では起動不可。
x86_64_v3-*2013 年以降の Haswell(Intel)または 2015 年以降の Excavator(AMD)以降の 64 ビット CPU 向け。AVX、AVX2、MOVBE 等搭載。古い CPU では起動不可。
x86_64_v4-*一部の AVX-512 命令搭載の 64 ビット Intel/AMD CPU 向け。2017 年以降の Intel CPU 対象だが、全ての Intel CPU が AVX-512 搭載というわけではない。

SIMD命令を有効にしたx86_64_v2-*, x86_64_v3-*, x86_64_v4-*は対応していないCPUで実行するとクラッシュします。 ドキュメントによると、Linuxでは*-unknown-linux-gnuが、Windows では*-windows-msvc-sharedが推奨されています。macOSはCPUに合わせて選べば良いです。

ここに書かれていないarmv7などのアーキテクチャでも、実際のReleaseには含まれているので確認してみてください。

ビルド設定

  • pgo+lto: Profile guided optimizationとLink-time optimizationをビルド時に適用している。最も高速なディストリビューション
  • pgo: Profile guided optimizationのみを適用
  • lto: Link-time optimizationのみを適用
  • noopt: 通常の最適化のみを行ったビルド
  • debug: 最適化を行っていないデバッグビルド

同梱内容

  • install_only: ビルド後のインストールに必要なファイルのみ
  • install_only_stripped: install_onlyからデバッグシンボルを削除した軽量版
  • full: ビルドに使用したファイル・成果物全てが同梱されている。.tar.zst 形式での配布

上記の違いについて、容量を見てみます。

バリエーション容量
cpython-3.12.4+20240726-x86_64-unknown-linux-gnu-install_only.tar.gz60.5MB
cpython-3.12.4+20240726-x86_64-unknown-linux-gnu-install_stripped.tar.gz21.2MB
cpython-3.12.4+20240726-x86_64-unknown-linux-gnu-pgo+lto-full.tar.zst87.3MB
cpython-3.12.4+20240726-x86_64-unknown-linux-gnu-pgo-full.tar.zst47.8MB

Dockerでの利用

Dockerfileでpython-build-standaloneから入手したPythonを導入してみます。

今回は、cpython-3.11.9+20240726-x86_64-unknown-linux-gnu-pgo+lto-full.tar.zst をdebian:latestのイメージにインストールします。

FROM --platform=linux/amd64 debian:latest

ARG TAG="20240726"
ARG PYTHON_VERSION="3.11.9"

RUN rm -f /etc/apt/apt.conf.d/docker-clean \
    && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && apt-get install -y --no-install-recommends \
    curl \
    ca-certificates \
    zstd

RUN curl -sSL "https://github.com/indygreg/python-build-standalone/releases/download/${TAG}/cpython-${PYTHON_VERSION}+${TAG}-x86_64-unknown-linux-gnu-pgo+lto-full.tar.zst" -o python.tar.zst \
    && tar -axvf python.tar.zst \
    && mv python/install /usr/local/python \
    && rm -rf python.tar.zst python
ENV PATH="/usr/local/python/bin:$PATH"
ENV LD_LIBRARY_PATH="/usr/local/python/lib:$LD_LIBRARY_PATH"
docker build -f Dockerfile ./ -t debian-python

docker run --rm -it debian-python python
Python 3.11.9 (main, Jul 25 2024, 22:42:09) [Clang 18.1.8 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

無事Pythonのインタープリターが起動しました。

Dockerコンテナ内で好きなバージョンのPythonを導入するには、aptのリポジトリppa:deadsnakes/ppaを登録するか、 pyenv, poetryなどでビルドするか、自前でビルドするくらいしか選択肢がありませんでしたが、 python-build-standaloneを利用することで、簡単に環境構築ができます。 特に、NVIDIAのDockerイメージであるnvidia/cudaといったイメージはデフォルトではPythonが 入っていないのでこの方法であれば、手軽にPython環境を追加できます。

まとめ

今回はpython-build-standaloneで配布されている様々なOS、アーキテクチャに対応したビルド済みPythonを Dockerへの導入する方法を紹介しました。 この方法であれば、新たにビルドすることなく、手軽にPython環境を構築することが可能です。