1. はじめに
開発用PCはインターネットにつながっているけど、使いたいパソコンはインターネットに接続できない・・・な~んてことは仕事をしていればちょくちょく遭遇します。
そんな時、開発環境をそっくりそのままインターネットに接続できないパソコンにインストールするには、ネットに繋がるPCでライブラリをダウンロードし、USBメモリ等で転送してオフラインPCでインストールする方法を検討しましたのでその手順を紹介します。
上に書いた通り、pipやuvなどのパッケージマネージャは通常インターネット接続が必要です。オフライン環境では「事前ダウンロード&オフラインインストール」が基本となります。
前提
- 開発用PCとインターネットに接続できないインストール先のPCの
- OSはおなじ
- Pythonのバージョンはおなじ
- こんなめったにない環境について語っている時点でまぁ アレ だと思い生ぬるく見守る読者www
過去にはこんな記事も書いていたようだ・・・💦
2. 依存関係の抽出
まず、開発環境でインストールしたいパッケージがまとめて記載された requirements.txt を準備します。
pip freeze > requirements.txt
# uv pip freeze >> requirements.txt
既存環境から直接抽出する場合、上記コマンドで必要パッケージ一覧を生成できます。
3. ライブラリの事前ダウンロード
ネット接続可能なPCで以下のPythonスクリプトを用いて依存パッケージ一式をダウンロードします。
(すべての依存関係を一括収集できるのがポイントです)
import subprocess
import sys
import os
import shutil
def download_libs_func(requirements_file='requirements.txt', output_dir='./libs/'):
'''
指定されたパッケージをダウンロードします。
Args:
requirements_file: 依存関係が記載されたrequirements.txtのパス
output_dir: ダウンロードしたパッケージの保存先ディレクトリ
Returns:
error_list: ダウンロードに失敗したパッケージのリスト
'''
os.makedirs(output_dir, exist_ok=True)
with open(requirements_file, encoding="utf-8") as f:
packages = f.read().splitlines()
error_list = []
for package in packages:
print(f"Downloading {package}...")
try:
subprocess.check_call(['pip', 'download', '--only-binary=:all:', '--dest', output_dir, package])
except subprocess.CalledProcessError as e:
print(f"Failed to download {package}: {e}")
error_list.append(package)
return error_list
if __name__ == '__main__':
error_list = download_libs_func('./requirements.txt', './libs/')
if error_list:
print("以下のパッケージのインストールに失敗しました:")
for pkg in error_list:
print(pkg)
else:
print("すべてのパッケージが正常にダウンロードされました。")
このスクリプトを実行すれば、./libs/ フォルダにすべての必要なホイール(.whl)ファイル等がダウンロードされます。
4. オフラインPCへのパッケージ転送
ダウンロードした libs フォルダをUSBメモリ等でオフラインPCに移します。この時同じバージョンのPythonのインストーラーもダウンロードしておきます。当然、requirements.txt も必ず一緒にコピーしてください。
5. オフラインインストール
オフラインPCでは、まずPythonのインストーラーを起動してインストールしておきます。
そのうえで以下のスクリプトを実行すると、「ローカルにあるパッケージ群のみ」を使ってインストールできます。
import os
import subprocess
def install_packages(package_dir, requirements):
try:
subprocess.check_call([
'.venv\Scripts\python.exe', '-m', 'pip', 'install', '--no-index', '--find-links', package_dir, '-r', requirements
]) # Windows仮想環境を例示
# subprocess.check_call(['uv', 'pip', 'install', '--no-index', '--find-links', package_dir, '-r', requirements]) # uv利用時
print("ライブラリのインストールが完了しました。")
except subprocess.CalledProcessError as e:
print(f"インストール中にエラーが発生しました: {e}")
if __name__ == '__main__':
package_dir = './libs/' # ライブラリが保存されたディレクトリ
requirements = './requirements.txt'
install_packages(package_dir, requirements)
「--no-index」でネット参照を禁止、「--find-links」で指定したローカルディレクトリのみからインストールするよう指定しています。
6. 補足・注意点
- pipのバージョンとPythonバージョン、OSは合わせておくとトラブル回避できます
- venvのパス指定に注意してください(パスを指定しないとグローバル環境にインストールしてしまう。)
- 依存関係が複雑な場合は、ダウンロード漏れがないか
error_listで念入りにチェックしましょう
7. おわりに
私の備忘録の完成です。
どなたか、一人でもいいので参考になれば、私は大満足です。
こういうくだらないことをやるのって、結構楽しい。www