pex とは
pex(Python EXecutable)は、Pythonアプリケーションとその依存ライブラリをまとめて1つの .pex ファイルに梱包するツールだ。生成された .pex ファイルはPythonインタープリタさえあれば実行でき、pip install や仮想環境のセットアップなしにそのまま動く。GitHubリポジトリ pex-tool/pex で開発されており、Twitter(現X)の社内ツールチェーンでも採用実績がある。
.pex ファイルの仕組み
.pex ファイルの実体はZIPアーカイブだ。先頭にshebangと小さなブートストラップスクリプトが埋め込まれており、Pythonはそのファイルを直接実行できる。内部には以下が含まれる。
- 依存パッケージのwheelまたはegg
- エントリポイントの情報
- Pythonバージョンや対応プラットフォームのメタデータ
実行時にブートストラップスクリプトが sys.path を設定し、指定したエントリポイントを呼び出す。OSの標準Pythonを使うため、Dockerイメージに余計なレイヤーを積まずに済む場面でも重宝される。
インストールと基本的な使い方
pex 自体は pip でインストールする。
pip install pex最もシンプルな例として、requests を含む実行ファイルを作る場合は次のようになる。
pex requests -o requests_bundle.pexエントリポイントを指定してCLIツールを梱包するには -e オプションを使う。
pex mypackage -e mypackage.cli:main -o myapp.pex./myapp.pexロックファイルを生成して再現性を担保したいときは pex3 lock create サブコマンドを使う。これにより依存関係を固定した requirements.lock 相当のファイルが作られ、CI/CDパイプラインでの配布に向く。
venv との違いと使い分け
venv や virtualenv はディレクトリ構造で依存を管理するため、そのままでは別マシンに持ち運べない。pex はその問題を「単一ファイル」という形で解決する。
ただし .pex ファイルはバイナリの拡張モジュール(C拡張)を含む場合、ビルド環境とターゲット環境のプラットフォームが一致していなければならない。純粋なPythonだけで構成されたパッケージなら、Linuxでビルドした .pex をmacOSで動かすといった使い方も問題なく動作する。
マルチプラットフォーム向けには --platform オプションで複数のターゲットを指定し、それぞれのwheelを同梱する方法がある。
pex mypackage \ --platform linux-x86_64-cp-311-cp311 \ --platform macosx-13-x86_64-cp-311-cp311 \ -o myapp.pex実運用での注意点
.pex ファイルの起動時、初回はZIPを展開してキャッシュを ~/.pex/install 以下に作成する。2回目以降はキャッシュが再利用されるため起動は速いが、コンテナ環境でキャッシュが毎回破棄される場合は PEX_ROOT 環境変数でキャッシュ先をボリュームマウントしたディレクトリに向けると起動コストを抑えられる。
また、PEX_INTERPRETER=1 を設定してファイルを実行すると、梱包された依存が読み込まれた対話型シェルとして使えるため、デバッグ時に便利だ。