オフライン環境のPythonプロジェクトを救う! requirements.txtからwheelをまとめてインストールする方法
はじめに
皆さんは、インターネットに接続できないオフライン環境でPythonの環境構築をする際に、困った経験はありませんか?
- セキュリティポリシーが厳格な社内サーバー
- クローズドなネットワークに設置されたIoTデバイス
- 外部アクセスを遮断したCI/CD環境
こういった環境では、おなじみの pip install -r requirements.txt
が使えず、パッケージのインストールに多大な労力がかかります。依存関係にあるパッケージを一つ一つ手作業で探し、ダウンロードして、正しい順序でインストールする…考えただけでも大変な作業です。
この記事では、そんなオフライン環境でのPythonパッケージインストール問題を、2つのシンプルなスクリプトを使ってスマートに解決する方法をご紹介します。
課題:オフライン環境でのパッケージインストール
オフライン環境で pip
を使った環境構築が難しい理由は、主に以下の2点です。
-
依存関係の解決:
requests
をインストールしたいだけなのに、実際にはcharset-normalizer
やurllib3
など、多くの依存パッケージが必要です。オフラインでは、これらの依存関係を自動で解決してくれないため、手動で全て把握する必要があります。 - 適切なファイルの選定: Pythonのパッケージ(特にC拡張を含むもの)は、OS、アーキテクチャ(x86_64, arm64など)、Pythonのバージョンによって、インストールすべきファイル(ホイールファイル)が異なります。間違ったファイルを選んでしまうと、インストールに失敗します。
これらの課題を解決するため、今回は以下の2つのツールを連携させて使います。
-
Moge800/download_requirements_wheels: オンライン環境で、
requirements.txt
をもとに依存関係を全て解決し、必要なホイールファイル(.whl
)をダウンロードしてくれるツール。 - Moge800/install_offline_wheels: オフライン環境で、ダウンロード済みのホイールファイル群を使ってパッケージを一括インストールしてくれるツール。
手順1: オンライン環境でホイールファイルを一括ダウンロード
まずはインターネットに接続できる環境で、オフライン環境に持っていくための準備をします。
準備
download_requirements_wheels
を git clone
します。
git clone https://github.com/Moge800/download_requirements_wheels.git
cd download_requirements_wheels
次に、インストールしたいパッケージを記述したrequirements.txt
を用意します。
スクリプトの実行
用意ができたら、スクリプトを実行します。引数にrequirements.txt
のパスを渡すだけです。
./launch.ps1
スクリプトが完了すると、ディレクトリが作成され、その中にrequirements.txt
に記載したパッケージと、それらが依存する全てのパッケージのホイールファイル(.whl
)がダウンロードされています。
downloads/
├── beautifulsoup4-4.12.3-py3-none-any.whl
├── soupsieve-2.5-py3-none-any.whl
├── requests-2.32.3-py3-none-any.whl
├── charset_normalizer-3.3.2-py3-none-any.whl
├── idna-3.7-py3-none-any.whl
├── urllib3-2.2.2-py3-none-any.whl
├── certifi-2024.7.4-py3-none-any.whl
├── pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
├── numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
├── python_dateutil-2.9.0.post0-py2.py3-none-any.whl
├── pytz-2024.1-py2.py3-none-any.whl
└── six-1.16.0-py2.py3-none-any.whl
...
手順2: オフライン環境でホイールファイルを一括インストール
次に、先ほど作成したdownloads
ディレクトリをUSBメモリなどを使ってオフライン環境へ持っていきます。
準備
オフライン環境側で、install_offline_wheels
を用意します。(こちらもオンライン環境から持っていく必要があります)
# 事前にオンライン環境から持ってきたリポジトリ
cd install_offline_wheels
downloads
ディレクトリがinstall_offline_wheels
ディレクトリ内にあるとします。
.
└── install_offline_wheels/
├── downloads/
└── (その他のファイル)
スクリプトの実行
準備ができたら、インストールスクリプトを実行します。
./launch.ps1
これだけで、pip
はインターネットにアクセスすることなく、指定されたディレクトリ内にあるファイルだけを使って、全てのパッケージを依存関係を考慮しながらインストールしてくれます。
内部的には、pip
の--no-index
PyPIのインデックスを見ない)と--find-links
パッケージを探すローカルのパスを指定)オプションが使われており、オフラインインストールの定石に沿った方法で実行されます。
まとめ
今回紹介した2つのツールを使うことで、
オンライン環境で依存関係を含めて全てダウンロード → オフライン環境で一括インストール
という、シンプルで確実なワークフローを構築できます。
これにより、手作業によるパッケージのダウンロード漏れや、バージョンの不整合といったミスを防ぎ、オフライン環境でのPython環境構築を劇的に効率化することができます。
非常にシンプルなスクリプトで実現されているため、カスタマイズしやすいのも魅力です。ぜひ、皆さんのプロジェクトでも活用してみてください。
この記事は、GoogleのAIであるGeminiによって作成されました。
AIって便利ですね。
オンライン/オフライン環境でOSやアーキテクチャ違いには対応していません。
X86Windwos64bitオンライン機であればX86Windwos64bitのオフライン機にのみ対応します。