オフライン環境でPythonパッケージをpipインストール
Contents
はじめに
世の中のシステムには、セキュリティ等の理由から外部ネットワークとの接続が遮断されているケースがあります。その場合、インターネット上から直接ソフトウェアのパッケージを取得してインストールを行うことができません。
上記のようなオフライン環境でPythonのパッケージをインストールする方法を調べてみました。
前提条件
Python 3.9.6
で検証しています。
OSは、CentOS Stream 8インストールDVDのISOファイルから「最小限のインストール」を選択しインストールを行いました。
バージョン情報は以下の通りです。
# cat /etc/redhat-release
CentOS Stream release 8
# uname -r
4.18.0-301.1.el8.x86_64
必要パッケージのインストール
「最小限のインストール」でOSをインストールした場合、ユーザプログラム向けのPythonがインストールされていないのでインストールを行います。また、サーバ間でファイルを転送する際の圧縮・展開のためにtar
も併せてインストールします。オフライン環境の場合、OSのISOイメージなどからインストールしてください。
$ sudo dnf install -y python39 tar
パッケージファイルの取得
まずは、インターネット接続環境のサーバを使用して、インストール対象のパッケージファイルをインターネット上から取得します。
仮想環境へ切り替え
パッケージファイル取得の前に、既存環境を汚さないように仮想環境を作成し、環境を切り替えます。
$ python3 -m venv .venv
$ source .venv/bin/activate
pipのアップデート
pip
モジュールが古いとパッケージファイルの取得に失敗することがあるので、最新バージョンに更新します。
$ pip install -U pip
(略)
Successfully installed pip-21.2.4
パッケージファイルの取得(個別取得)
パッケージを個別に取得する場合は、引数にパッケージ名を指定してpip download
を実行します。-d
オプションで、ダウンロード先のディレクトリを指定できます。ディレクトリの指定がない場合は、カレントディレクトリにパッケージファイルが保存されます。
以下の例では、ansible
および依存関係にあるパッケージをカレントディレクトリ直下のpackages
ディレクトリに保存します。
$ pip download -d ./packages ansible
(略)
Saved ./packages/ansible-4.5.0.tar.gz
Saved ./packages/ansible-core-2.11.4.tar.gz
Saved ./packages/resolvelib-0.5.4-py2.py3-none-any.whl
Saved ./packages/cryptography-3.4.8-cp36-abi3-manylinux_2_24_x86_64.whl
Saved ./packages/cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl
Saved ./packages/Jinja2-3.0.1-py3-none-any.whl
Saved ./packages/MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Saved ./packages/packaging-21.0-py3-none-any.whl
Saved ./packages/pyparsing-2.4.7-py2.py3-none-any.whl
Saved ./packages/pycparser-2.20-py2.py3-none-any.whl
Saved ./packages/PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl
Successfully downloaded ansible ansible-core resolvelib cryptography cffi jinja2 MarkupSafe packaging pyparsing pycparser PyYAML
なお、引数として渡すパッケージ名はバージョン指定することも可能です。
例:pip download -d ./packages ansible==4.5.0
パッケージファイルの取得(一括取得)
複数のパッケージファイルを一括で取得する場合、requirements.txt
に一覧を記載すると一括指定できて便利です。
テキストエディタを使用して、事前にrequirements.txt
ファイルを作成しておきます。
$ cat requirements.txt
ansible
ansible-core
resolvelib
cryptography
cffi
jinja2
MarkupSafe
packaging
pyparsing
pycparser
PyYAML
pip download
コマンドに-r
オプションを付けると、requirements.txt
に記載のパッケージファイルを取得できます。
$ pip download -d ./packages -r requirements.txt
(略)
Saved ./packages/ansible-4.5.0.tar.gz
Saved ./packages/ansible-core-2.11.4.tar.gz
Saved ./packages/resolvelib-0.5.4-py2.py3-none-any.whl
Saved ./packages/cryptography-3.4.8-cp36-abi3-manylinux_2_24_x86_64.whl
Saved ./packages/cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl
Saved ./packages/Jinja2-3.0.1-py3-none-any.whl
Saved ./packages/MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Saved ./packages/packaging-21.0-py3-none-any.whl
Saved ./packages/pyparsing-2.4.7-py2.py3-none-any.whl
Saved ./packages/pycparser-2.20-py2.py3-none-any.whl
Saved ./packages/PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl
Successfully downloaded ansible ansible-core resolvelib cryptography cffi jinja2 MarkupSafe packaging pyparsing pycparser PyYAML
圧縮アーカイブファイル化
後ほどオフライン環境のサーバへファイルを転送しやすいように、packages
ディレクトリを圧縮アーカイブファイルにまとめます。
$ tar zcvf packages.tar.gz ./packages
$ ls -l packages.tar.gz
-rw-rw-r--. 1 hoshino hoshino 46412021 9月 4 01:04 packages.tar.gz
パッケージのローカルインストール
ここからは、パッケージのインストールを行いたいオフライン環境のサーバで作業を行います。同サーバにパッケージをローカルインストールします。
パッケージファイルの転送
パッケージファイルの取得
で作成した圧縮アーカイブファイルを、オフライン環境のサーバに転送します。同ファイルの内容を任意の場所に展開します。
$ ls -l packages.tar.gz
-rw-rw-r--. 1 hoshino hoshino 46412021 9月 4 01:04 packages.tar.gz
$ tar zxvf packages.tar.gz
./packages/
./packages/ansible-4.5.0.tar.gz
./packages/ansible-core-2.11.4.tar.gz
./packages/resolvelib-0.5.4-py2.py3-none-any.whl
./packages/cryptography-3.4.8-cp36-abi3-manylinux_2_24_x86_64.whl
./packages/cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl
./packages/Jinja2-3.0.1-py3-none-any.whl
./packages/MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
./packages/packaging-21.0-py3-none-any.whl
./packages/pyparsing-2.4.7-py2.py3-none-any.whl
./packages/pycparser-2.20-py2.py3-none-any.whl
./packages/PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl
仮想環境へ切り替え
パッケージインストール対象のサーバでも、既存環境を汚さないように仮想環境を作成し、環境を切り替えます。
$ python3 -m venv .venv
$ source .venv/bin/activate
パッケージのローカルインストール(個別インストール)
パッケージを個別にインストールする場合は、引数にパッケージ名を指定してpip install
を実行します。--no-index
オプションでインデックスサーバ(PyPI)への参照を無効化し、代わりに--find-links
オプションで指定したディレクトリ内からパッケージを検索します。
以下の例では、ansible
および依存関係にあるパッケージをカレントディレクトリ直下のpackages
ディレクトリから検索しインストールします。
$ pip install --no-index --find-links=./packages ansible
(略)
Successfully installed MarkupSafe-2.0.1 PyYAML-5.4.1 ansible-4.5.0 ansible-core-2.11.4 cffi-1.14.6 cryptography-3.4.8 jinja2-3.0.1 packaging-21.0 pycparser-2.20 pyparsing-2.4.7 resolvelib-0.5.4
なお、pip
のバージョンが古いとパッケージのインストールに失敗する場合があります。その場合は、pip
自体を先にアップデートします。pip
のパッケージファイルを事前に取得しておき、他パッケージをインストールする前に以下の要領でアップデートします。
$ pip install -U --no-index --find-links=./packages pip
パッケージのローカルインストール(一括インストール)
複数のパッケージファイルを一括でインストールする場合、requirements.txt
を使用します。requirements.txt
は、パッケージファイルの取得(一括取得)
で使用したものをオフライン環境のサーバへ転送します。
pip install
コマンドに-r
オプションを付けると、requirements.txt
に記載のパッケージファイルを一括インストールできます。
$ pip install --no-index --find-links=./packages -r requirements.txt
(略)
Successfully installed MarkupSafe-2.0.1 PyYAML-5.4.1 ansible-4.5.0 ansible-core-2.11.4 cffi-1.14.6 cryptography-3.4.8 jinja2-3.0.1 packaging-21.0 pycparser-2.20 pyparsing-2.4.7 resolvelib-0.5.4
インストール済みパッケージの確認
ローカルインストールが完了したら、pip list
で対象パッケージがインストールされていることを確認します。
$ pip list
Package Version
------------ -------
ansible 4.5.0
ansible-core 2.11.4
cffi 1.14.6
cryptography 3.4.8
Jinja2 3.0.1
MarkupSafe 2.0.1
packaging 21.0
pip 21.2.4
pycparser 2.20
pyparsing 2.4.7
PyYAML 5.4.1
resolvelib 0.5.4
setuptools 50.3.2