NHN Cloud Meetup 編集部
本番!Pythonの実行環境を設定する
2019.10.09
5,662
背景
Linux環境においてPythonで安定したサービスアプリケーションを提供するための環境づくりについて紹介します。
Pythonランタイムは、各OSで使用されているパッケージマネージャやインストーラーを利用して正常にインストールされていると仮定しましょう。しかし、実際にPythonを利用したサービス環境を構築するには、より精密な設定が必要です。
まず、Pythonランタイムのバージョンに敏感なアプリケーションがなければ、基本インストールされたPython3ランタイムをPATH環境変数に追加して使用すればよいです。しかし、サービス環境では、外部ライブラリの依存性管理や、同一ホストから別バージョンへのランタイムが必要なケースなど、様々な問題があるでしょう。
Pythonの生態系では、venv、virtualenv、pyenv、pyenv-virtualenv、virtualenvwrapper、pipenvなど、人気のあるツールがいくつかあります。インターネット上に様々なツールの説明がありますが、ここでは最近の新しいツール(pyenv、pipenv)の活用法を重点的に紹介します。
アプリケーションによって要件が少し異なる場合がありますので、段階的に説明します。
- 独自開発したPythonモジュールを任意のパスに設置して使用する
- 外部Pythonライブラリの依存性を分離して管理する
- Python環境を分離して管理する
- 分離された仮想環境に名前をつける
1.独自開発したPythonモジュールを任意のパスに設置して使用する
この場合は特別なツールは必要ありません。シェルの環境変数PYTHONPATHを利用できます。
export PYTHONPATH = Pythonライブラリが設置されているパス
コロン(:)記号を区切り文字にして複数パスを指定すると、Pythonランタイムがインポートするときに、この環境変数に指定した順にモジュールをナビゲートします。
2.外部Pythonライブラリの依存性を分離して管理する
pip
外部Pythonライブラリは、バージョンを適切に管理する必要があるため、Pythonランタイムパッケージに含まれるpipを利用します。3.xバージョンでは、pip3という名前で提供されているので、明示的にpip3で実行してもよいし、PATH環境変数で実行時のパスが指定されている場合は、pipから実行してよいでしょう。
初期に外部Pythonライブラリを設置するときは、まず検索して見ることができます。次のコマンドを利用することもありますが、通常はあまりにも多くの検索結果が出力されるため、grepでフィルタリングする必要があります。
pip3 search ライブラリ名
PyPIウェブサイトで参照できます。
次のコマンドでインストールできます。(ただし、実際にインストールしないでください。理由は下で説明します。)
pip3 install ライブラリ名
このように設置されたライブラリでは、バージョンを適切に管理した方がよいでしょう。特にサービスを安定的に持続しようとするなら、バージョンは特定バージョンに固定することをお勧めします。次の2つのコマンドラインは、記憶しておく必要があります。
pip3 freeze > requirements.txt
上記のfreezeではコマンド発行時点のパッケージ情報を確認しつつ、管理設定ファイルの「requirements.txt」を書き出しています。requirements.txtはgitなどでバージョン管理しておくとよいです。以下のコマンドではこの設定ファイルを使用して、新しい環境でも同じようにライブラリを再インストールしています。
pip3 install -r requirements.txt
ここまでがpipの基本的な使い方です。Pythonの開発経験があれば、誰もが知っている内容でしょう。しかし、pipで外部ライブラリをインストールする場合、/usrの下位にインストールする必要があるため、root権限も必要となり、システム共通環境に影響を及ぼすため、サービス用として使用するサーバーならリスクが大きくなります。(pip3 installはなるべく避けた方がよいでしょう。)
virtualenv
同一サーバー内に独立した複数の開発環境を構築しようと思った際、かつてはvirtualenvが標準的な方法でした。ただし、現在はpyenvとpipenvで代替可能なため、virtualenvの説明は簡単にしてスルーします。
原理は簡単です。現在使用可能なPythonランタイムをディレクトリのまま個人ディレクトリにコピーしておき、それをグローバルのランタイムのように使用する方法です。
virtualenvは、Pythonの外部ライブラリの依存性を分離して使用できるようにした初の試みでもありました。古い方法ですが、環境分離という概念はすべてここから出発したと言えます。
pipenv
ここではvirtualenvは忘れて、pipenvを使いましょう。pipenvはvirtualenvの公式的な継承者と言えます。
まず、次のように設置します。
pip3 install pipenv
pipenvはrequirements.txtの代わりに、PipfileとPipfile.lockに依存性を管理します。
初期化します。このコマンドは、復元する際にも同様に使用します。
pipenv install
仮想環境を有効にします。
pipenv shell
外部ライブラリを設置しましょう。
pipenv install beautifulsoup4 pip list
削除します。
pipenv uninstall beautifulsoup4 pip list
pip freezeと同じコマンドです。Pipfile.lockファイルを作成し、ランタイムと下位の依存性を含むすべての依存性に対する情報を記録するため、完全な同一環境を再構築します。
pipenv lock
このコマンドを実行した後、PipfileとPipfile.lockをgitにコミットするとよいでしょう。
PipfileとPipfile.lockを保持し、同じ依存性を持つ環境を復元するには、初期化で使用したinstallを実行します。
pipenv install
3. Python環境を分離して管理する
様々な理由で、ランタイムの分離が必要になる場合があります。例えば、同じホストのアプリケーションにおいて、一方はPython 3.5のバージョンを必要とし、他のアプリケーションではPython 3.7を必要とする場合、2つのランタイムをインストールしなければなりません。システムパスにPythonをバージョン別にインストールするのは現実的に厳しく、また望ましくありません。
また、ランタイムに名前をつけて管理したい場合もあるでしょう。このような場合には、pyenvとpyenv-virtualenvを活用すると便利です。
pyenvインストール
次のコマンドを実行して、ホームディレクトリの下位に.pyenvを設置します。
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
pyenvを実行できるように、環境変数として追加する設定を.bashrcに作成します。
export PYENV_ROOT=$HOME/.pyenv export PATH=$PYENV_ROOT/bin:$PATH if command -v pyenv 1>/dev/null 2>&1; then eval "$(pyenv init -)" fi
これでpyenvを使用するための準備は終わりました。
ランタイムのインストール
pyenvに必要なPythonランタイムを選んで自分だけのPython実行環境を作ってみましょう。
まず、設置できるランタイムのバージョンリストを選択します。
pyenv install -l
2019年4月時点の最新バージョンに3.7.3が存在しました。これを設置してみましょう。ソースコードをダウンロードしてビルドするので、gccパッケージとmakeパッケージがインストールされていなければなりません。必須ライブラリであるlibffi-devel、zlib-develとopenssl-develパッケージもあらかじめインストールされていると仮定します。上述したようにソースビルドが非常に複雑なため推奨していませんが、pyenvでインストールする場合は必須パッケージで、うまく設置されていれば大きな問題もなく、自動でソースビルドが成功します。
pyenv install 3.7.3
インストールが完了したら、設置状況を確認できます。
pyenv versions * system (set by /home/test/.pyenv/version) 3.7.3
systemと3.7.3がリストに表示されるでしょう。
ランタイムの有効化と使用
このように設置されたランタイムは~/.pyenv下位にインストールされているだけで、すぐに使用できるわけではなく、特定のランタイムを選択して有効にする過程が必要です。(次のコマンドは昔ながらの方法で従う必要はありません。)
pyenv shell 3.7.3 pyenv activate pyenv activateを実行するには項目4でインストールされているpyenv-virtualenvが必要。
このようなコマンドを覚えて毎回入力して使用するのは煩わしいですね。次の方法で面倒なプロセスをすべて省略して使用することができます。
pyenv local
重要:特定ディレクトリの下位から、特定ランタイムと外部ライブラリの依存性を別途分離して、自動的に適用されるようにできます。
pyenv local 3.7.3
このコマンドが実行されると、当該ディレクトリに.python-versionファイルが作成され、ここにバージョンを記録します。以降も、当該ディレクトリと下位に進入する度に、バージョン3.7.3のランタイムが自動で有効になります。当該ディレクトリを抜けると自動で無効になり、グローバルに使用するランタイムが選択されます。これはpyenvの最大の利点だと言えます。
自分が使用しているランタイムのバージョンを確認したい場合は、次のコマンドで確認できます。
pyenv version
pyenv global
グローバルに使用するランタイムは、基本的にバージョン2.7.5で、systemという名前で通用されます。もしグローバルに使用するランタイムをバージョン3.7.3に変更するなら、次のコマンドで実行できます。
pyenv global 3.7.3
2.7.5に戻したい場合は…
pyenv global system
pyenvの使用方法が複雑に見えるので整理します。次の3つのコマンドだけ覚えましょう。その中で最も重要なのはlocalコマンドです。
インストール:pyenv install 3.7.3
特定ディレクトリのバージョンを指定:pyenv local 3.7.3
バージョン確認:pyenv version
4.分離された仮想環境に名前をつける
pyenvを拡張してvirtualenv機能を使用することができます。pyenv-virtualenvという素晴らしいツールがあります。
次のようにインストールします。
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
.bashrcファイルにpyenv設定を追加したように、pyenv-virtualenvの初期化設定を追加します。
if command -v pyenv 1>/dev/null 2>&1; then eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" fi
先ほどインストールした3.7.3環境に別の名前をつけて使用します。v3という分離された仮想環境が得られました。
pyenv virtualenv 3.7.3 v3
インストールして使用可能なバージョンを確認します。
pyenv versions * system (set by /home/test/.pyenv/version) 3.7.3 3.7.3/envs/v3 v3
v3という名前の仮想環境が生じたことを確認できます。1つだけ作って使用するなら、あえて仮想環境を使う必要はありません。実際の環境である3.7.3は、1つだけインストールしておき、仮想環境を複数作っておけば分離された環境で使用することができます。
pyenv virtualenv 3.7.3 v3_test_env pyenv versions * system (set by /home/test/.pyenv/version) 3.7.3 3.7.3/envs/v3 3.7.3/envs/v3_test_env v3 v3_test_env
v3環境とv3_test_env環境がすべて3.7.3ランタイム基盤に、別途分離された環境で準備できました。
pyenv localを使って、特定ディレクトリで使用する仮想環境を設定します。
cd ~/my_work_dir pyenv local v3 pip list cd ~/my_test_dir pyenv local v3_test_env pip list
同じく以降、当該ディレクトリに入る度、定められた仮想環境が自動で有効になります。
アップグレード
Python仮想環境のバージョンを変更する場合は、新規ランタイムをpyenv installにインストールした上で、仮想環境を消去して、新しいランタイムに基づいて設定することも可能です。
pyenv install 3.7.4 pyenv versions pyenv uninstall v3 pyenv virtualenv 3.7.4 v3
もちろん、このようなアップグレード作業の前に、pipenv lockを用いて依存性情報を固定しておく必要があります。
この仮想環境でサービス形態でPythonアプリケーションが実行されている場合、上記のようにアンインストールするのは難しいです。このような場合には、別途ディレクトリに新規の仮想環境を構築し、既存のサービスを停止して、新規の仮想環境で新たにサービスを開始することを推奨します。
結論
pyenvとpyenv-virtualenvの組み合わせにpipenvを加えて使用すると便利です。
gitでpyenvをインストールし、pip3でpyenv-virtualenvとpipenvだけをインストールしておけば、以降は、/usrの下位に外部ライブラリやツールをインストールする必要がありません。
pipenv vs pyenv
pipenvも非常に便利なツールですが、個人的にはpyenvがさらに便利だと感じるので、これを推奨します。環境を分離したり、自動設定を適用したり、より便利に使いたい場合は、pyenvを選択しましょう。また、ランタイムは分離する必要がなく、依存性のみを分離したい場合は、pipenvを選択するとよいでしょう。pyenvは、ランタイムの最初に1回ソースビルドしなければならないという負担がありますが、pipenvは実行する度にshellコマンドでアクティベートさせる過程がやや面倒です。
Anaconda
フルパッケージとして一度にすべてのパッケージを含めてインストールしたい場合は、Anacodaをお勧めします。yumやaptのようなシステムのパッケージマネージャを利用することもでき、ダウンロードしてインストールすることもできます。
Anacondaは、ランタイムと依存性を事前によくパッケージしておくことによって、簡単かつ迅速にインストールして使うことができますが、主にWindowsの環境やデータ分析用として使用します。
condaという名前のCLIツールを提供しますが、これを利用して仮想環境を作成し、追加的なパッケージをインストールできます。
conda create -n my_ana_env conda activate my_ana_env conda install lxml conda deactivate
pyenvまたはpipとほぼ同様の文法をサポートするため、詳細な説明は省略します。
Miniconda
Anacondaは、パッケージ構成がよくなっていますが、かなり大きいため、軽い環境では小さいサイズで構成されているminicondaを使用することもあります。同様にcondaを利用して、追加的なパッケージをインストールすることもできます。