web-dev-qa-db-ja.com

gitリポジトリ内にvirtualenvディレクトリを置くのは悪いですか?

アプリのgitリポジトリ内に作成するDjangoウェブアプリのvirtualenvを配置することを考えています。デプロイをシンプルかつ簡単に保つための簡単な方法のようです。これをしてはいけない理由はありますか?

235
Lyle Pratt

pip freeze を使用して、必要なパッケージを requirements.txt ファイルに入れ、リポジトリに追加します。 virtualenv全体を保存する理由を考えてみましたが、できませんでした。

248
RyanBrady

前述のように、virtualenvディレクトリをgitに保存すると、git cloneを実行するだけでアプリ全体をデプロイできます(さらに、Apache/mod_wsgiをインストールして構成できます)。このアプローチの潜在的に重要な問題の1つは、Linuxでは、フルパスがvenvのactivate、Django-admin.py、easy_install、およびpipスクリプトにハードコードされることです。これは、おそらく同じサーバーで複数の仮想ホストを実行するために異なるパスを使用する場合、virtualenvが完全に機能しないことを意味します。ウェブサイトは実際にはそれらのファイルの間違ったパスで動作する可能性があると思いますが、次にpipを実行しようとしたときに問題が発生するでしょう。

既に与えられている解決策は、デプロイ中にvirtualenvを作成し、必要なpipインストールを実行できるように、十分な情報をgitに保存することです。通常、人々はpip freezeを実行してリストを取得し、requirements.txtという名前のファイルに保存します。 pip install -r requirements.txtでロードできます。 RyanBradyはすでに、1行でdeployステートメントを文字列化する方法を示しました。

# before 15.1.0
virtualenv --no-site-packages --distribute .env &&\
    source .env/bin/activate &&\
    pip install -r requirements.txt

# after deprecation of some arguments in 15.1.0
virtualenv .env && source .env/bin/activate && pip install -r requirements.txt

個人的には、これらをgit cloneまたはgit pullを実行した後に実行するシェルスクリプトに入れるだけです。

また、virtualenvディレクトリを保存すると、pipのアップグレードを処理するのが少し難しくなります。アップグレードの結果ファイルを手動で追加/削除してコミットする必要があるためです。 requirements.txtファイルを使用して、requirements.txtの適切な行を変更し、pip install -r requirements.txtを再実行します。すでに述べたように、これにより「スパムの送信」も削減されます。

43

PyCryptoなどの環境に応じて異なる方法でコンパイルされるライブラリの使用を開始するまで、私は同じことをしていました。私のPyCrypto macはCygwinで動作しません。Ubuntuでは動作しません。

リポジトリを管理することは完全に悪夢になります。

いずれにしても、すべてをgitで保持するよりも、pipのフリーズと要件ファイルを管理する方が簡単であることがわかりました。それらのライブラリが更新されると、数千のファイルのコミットスパムを回避できるようになるので、それもきれいです...

35

発生する主な問題の1つは、virtualenvを他の人が使用できない可能性があることです。理由は、常に絶対パスを使用するためです。したがって、virtualenvがたとえば/home/lyle/myenv/にある場合、このリポジトリを使用する他のすべてのユーザーに対して同じと見なされます(完全に同じ絶対パスである必要があります)。あなたと同じディレクトリ構造を使用している人を推測することはできません。

より良い方法は、全員が独自の環境を設定し(virtualenvの有無にかかわらず)、そこにライブラリをインストールすることです。また、virtualenvがそれぞれ異なるプラットフォームにインストールされているため、異なるプラットフォーム(Linux/Windows/Mac)でコードをより使いやすくします。

15

アプリケーションを実行するオペレーティングシステムがわかっている場合は、システムごとに1つのvirtualenvを作成し、それをリポジトリに含めます。次に、アプリケーションで実行中のシステムを検出し、対応するvirtualenvを使用します。

システムは、例えば platform モジュールを使用して識別されます。

実際、これは私が書いた社内アプリケーションで行うことであり、必要に応じて新しいシステムのvirtualenvをすばやく追加できます。このように、pipがアプリケーションに必要なソフトウェアを正常にダウンロードできることに依存する必要はありません。私はまた、例えばのコンパイルについて心配する必要はありません。 psycopg2 使用しています。

アプリケーションがどのオペレーティングシステムで実行されるかわからない場合は、おそらく他の回答で提案されているpip freezeを使用することをお勧めします。

2
fredrik

基本的には David Sickmillerの答え を使用し、もう少し自動化します。私は、プロジェクトの最上位に次の内容のactivateという名前の(実行不可能な)ファイルを作成します。

[ -n "$BASH_SOURCE" ] \
    || { echo 1>&2 "source (.) this with Bash."; exit 2; }
(
    cd "$(dirname "$BASH_SOURCE")"
    [ -d .build/virtualenv ] || {
        virtualenv .build/virtualenv
        . .build/virtualenv/bin/activate
        pip install -r requirements.txt
    }
)
. "$(dirname "$BASH_SOURCE")/.build/virtualenv/bin/activate"

(Davidの回答によると、これは、要件のリストを最新に保つためにpip freeze > requirements.txtを実行していることを前提としています。)

上記は一般的な考え方を示しています。実際に使用する実際の activate スクリプト( documentation )はもう少し洗練されており、pythonを使用して-q(quiet)オプションを提供しますpython3は使用不可など.

これは、現在の作業ディレクトリから取得でき、適切にアクティブ化されます。必要に応じて、最初に仮想環境を設定します。私のトップレベルのテストスクリプトは通常、開発者が最初にアクティブ化する必要なく実行できるように、次の行に沿ってコードを持っています。

cd "$(dirname "$0")"
[[ $VIRTUAL_ENV = $(pwd -P) ]] || . ./activate

ここでは、activateではなく./activateを調達することが重要です。後者は、現在のディレクトリにあるものを見つける前に、パスで他のactivateを見つけるからです。

1
Curt J. Sampson

開発環境を設定するだけの場合は、gitレポジトリをクリーンにするcipフリーズファイルcazを使用します。

次に、実稼働展開を行う場合は、venvフォルダ全体をチェックインします。これにより、展開の再現性が向上し、libxxx-devパッケージが不要になり、インターネットの問題が回避されます。

そのため、2つのリポジトリがあります。メインソースコード用に1つ。requirements.txtが含まれています。また、envフォルダー全体を含むenvリポジトリ。

0
Shuo