将我的virtualenv目录放在git存储库中是否不好?

问题:将我的virtualenv目录放在git存储库中是否不好?

我正在考虑将virtualenv用于我在git存储库中创建的Django Web应用程序中。这似乎是使部署变得如此简单的一种简单方法。我为什么不应该这样做?

I’m thinking about putting the virtualenv for a Django web app I am making inside my git repository for the app. It seems like an easy way to keep deploy’s simple and easy. Is there any reason why I shouldn’t do this?


回答 0

我通常pip freeze将所需的软件包放入requirements.txt文件中,然后将其添加到存储库中。我试图思考为什么您要存储整个virtualenv的方法,但是我不能。

I use pip freeze to get the packages I need into a requirements.txt file and add that to my repository. I tried to think of a way of why you would want to store the entire virtualenv, but I could not.


回答 1

正如您指出的那样,将virtualenv目录存储在git中将允许您仅通过执行git clone(加上安装和配置Apache / mod_wsgi)来部署整个应用程序。这种方法的一个潜在的重大问题是,在Linux上,完整路径在venv的activate,django-admin.py,easy_install和pip脚本中进行了硬编码。这意味着,如果您想使用不同的路径,也许要在同一台服务器上运行多个虚拟主机,那么您的virtualenv将无法完全正常工作。我认为该网站实际上可能在这些文件中使用了错误的路径,但下一次尝试运行pip时会遇到问题。

已经给出的解决方案是在git中存储足够的信息,以便在部署过程中可以创建virtualenv并进行必要的pip安装。人们通常会跑步pip freeze以获取列表,然后将其存储在名为requirements.txt的文件中。可以加载pip install -r requirements.txt。RyanBrady已经展示了如何在一行中将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之后运行的shell脚本中。

存储virtualenv目录还使处理pip升级变得有些棘手,因为您必须手动添加/删除并提交升级后的文件。使用requirements.txt文件,您只需更改requirements.txt中的相应行并重新运行即可pip install -r requirements.txt。如前所述,这还减少了“提交垃圾邮件”。

Storing the virtualenv directory inside git will, as you noted, allow you to deploy the whole app by just doing a git clone (plus installing and configuring Apache/mod_wsgi). One potentially significant issue with this approach is that on Linux the full path gets hard-coded in the venv’s activate, django-admin.py, easy_install, and pip scripts. This means your virtualenv won’t entirely work if you want to use a different path, perhaps to run multiple virtual hosts on the same server. I think the website may actually work with the paths wrong in those files, but you would have problems the next time you tried to run pip.

The solution, already given, is to store enough information in git so that during the deploy you can create the virtualenv and do the necessary pip installs. Typically people run pip freeze to get the list then store it in a file named requirements.txt. It can be loaded with pip install -r requirements.txt. RyanBrady already showed how you can string the deploy statements in a single line:

# 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

Personally, I just put these in a shell script that I run after doing the git clone or git pull.

Storing the virtualenv directory also makes it a bit trickier to handle pip upgrades, as you’ll have to manually add/remove and commit the files resulting from the upgrade. With a requirements.txt file, you just change the appropriate lines in requirements.txt and re-run pip install -r requirements.txt. As already noted, this also reduces “commit spam”.


回答 2

在开始使用根据环境(例如PyCrypto)进行不同编译的库之前,我一直这样做。我的PyCrypto mac无法在Cygwin上运行,也无法在Ubuntu上运行。

管理存储库已成为一场噩梦。

无论哪种方式,我都发现管理点子冻结和需求文件比将其全部保存在git中更容易。它也更加干净,因为随着这些库的更新,您可以避免提交数千个文件的垃圾邮件…

I used to do the same until I started using libraries that are compiled differently depending on the environment such as PyCrypto. My PyCrypto mac wouldn’t work on Cygwin wouldn’t work on Ubuntu.

It becomes an utter nightmare to manage the repository.

Either way I found it easier to manage the pip freeze & a requirements file than having it all in git. It’s cleaner too since you get to avoid the commit spam for thousands of files as those libraries get updated…


回答 3

我认为出现的主要问题之一是virtualenv可能无法被其他人使用。原因是它始终使用绝对路径。因此,例如,如果您使用virtualenv,/home/lyle/myenv/它将对使用此存储库的所有其他用户都假设相同(其绝对路径必须完全相同)。您不能假定人们使用与您相同的目录结构。

更好的做法是每个人都在建立自己的环境(无论是否带有virtualenv)并在其中安装库。这也使您的代码在不同平台(Linux / Windows / Mac)上的可用性更高,这也是因为在每个平台上都不同地安装了virtualenv。

I think one of the main problems which occur is that the virtualenv might not be usable by other people. Reason is that it always uses absolute paths. So if you virtualenv was for example in /home/lyle/myenv/ it will assume the same for all other people using this repository (it must be exactly the same absolute path). You can’t presume people using the same directory structure as you.

Better practice is that everybody is setting up their own environment (be it with or without virtualenv) and installing libraries there. That also makes you code more usable over different platforms (Linux/Windows/Mac), also because virtualenv is installed different in each of them.


回答 4

我使用的基本上是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以使您的需求列表保持最新。)

以上给出了总体思路;实际的激活脚本(文档),我通常使用是有点更复杂,提供了-q(安静)选项,使用pythonpython3不可用等。

然后,可以从任何当前工作目录中获取该资源并将其正确激活,必要时首先设置虚拟环境。我的顶级测试脚本通常包含以下几行代码,因此无需开发人员先激活即可运行它:

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

这里的Sourcing ./activate(而不是activate)很重要,因为后者会activate在您的路径中找到其他任何路径,然后再在当前目录中找到其他路径。

I use what is basically David Sickmiller’s answer with a little more automation. I create a (non-executable) file at the top level of my project named activate with the following contents:

[ -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"

(As per David’s answer, this assumes you’re doing a pip freeze > requirements.txt to keep your list of requirements up to date.)

The above gives the general idea; the actual activate script (documentation) that I normally use is a bit more sophisticated, offering a -q (quiet) option, using python when python3 isn’t available, etc.

This can then be sourced from any current working directory and will properly activate, first setting up the virtual environment if necessary. My top-level test script usually has code along these lines so that it can be run without the developer having to activate first:

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

Sourcing ./activate, not activate, is important here because the latter will find any other activate in your path before it will find the one in the current directory.


回答 5

在回购协议中包含任何与环境相关的组件或设置作为使用回购协议的关键方面之一不是一个好主意,也许是与其他开发人员共享它。这是在Windows PC(例如Win10)上设置开发环境的方式。

  1. 打开Pycharm,然后在第一页上,选择从您的源代码管理系统中检出项目(在我的情况下,我正在使用github)

  2. 在Pycharm中,导航至设置,然后选择“项目解释器”,然后选择添加新虚拟环境的选项,您可以将其称为“ venv”。

  3. 选择位于C:\ Users {user} \ AppData \ Local \ Programs \ Python \ Python36的基本python解释器(请确保根据安装的内容选择适当的Python版本)

  4. 请注意,Pycharm将创建新的虚拟环境,并在项目文件夹内的venv文件夹下复制python二进制文件和所需的库。

  5. 让Pycharm完成其扫描,因为它需要重建/刷新项目框架

  6. 从git交互中排除venv文件夹(将venv \添加到项目文件夹中的.gitignore文件)

奖励:如果您希望人们轻松(很好,几乎很容易)安装软件所需的所有库,则可以使用

pip freeze > requirements.txt

并将说明放在git上,以便人们可以使用以下命令立即下载所有必需的库。

pip install -r requirements.txt 

It’s not a good idea to include any environment-dependent component or setting in your repos as one of the key aspects of using a repo, is perhaps, sharing it with other developers. Here is how I would setup my development environment on a Windows PC (say, Win10).

  1. Open Pycharm and on the first page, choose to check out the project from your Source Control System (in my case, I am using github)

  2. In Pycharm, navigate to settings and choose “Project Interpreter” and choose the option to add a new virtual environment , you can call it “venv”.

  3. Choose the base python interpreter which is located at C:\Users{user}\AppData\Local\Programs\Python\Python36 (make sure you choose the appropriate version of Python based on what you have installed)

  4. Note that Pycharm will create the new virtual environment and copy python binaries and required libraries under your venv folder inside your project folder.

  5. Let Pycharm complete its scanning as it needs to rebuild/refresh your project skeleton

  6. exclude venv folder from your git interactions (add venv\ to .gitignore file in your project folder)

Bonus: If you want people to easily (well, almost easily) install all the libraries your software needs, you can use

pip freeze > requirements.txt

and put the instruction on your git so people can use the following command to download all required libraries at once.

pip install -r requirements.txt 

回答 6

如果您知道您的应用程序将在哪个操作系统上运行,我将为每个系统创建一个virtualenv并将其包含在我的存储库中。然后,我将让我的应用程序检测它在哪个系统上运行,并使用相应的virtualenv。

该系统可以例如使用平台模块来识别。

实际上,这就是我对自己编写的内部应用程序所做的工作,可以在需要时快速添加新系统的virtualenv。这样,我不必依靠那个点就可以成功下载我的应用程序所需的软件。我也不必担心例如psycopg2的编译我使用。

如果您不知道您的应用程序可以在哪个操作系统上运行,那么最好pip freeze按照此处其他答案中的建议使用。

If you know which operating systems your application will be running on, I would create one virtualenv for each system and include it in my repository. Then I would make my application detect which system it is running on and use the corresponding virtualenv.

The system could e.g. be identified using the platform module.

In fact, this is what I do with an in-house application I have written, and to which I can quickly add a new system’s virtualenv in case it is needed. This way, I do not have to rely on that pip will be able to successfully download the software my application requires. I will also not have to worry about compilation of e.g. psycopg2 which I use.

If you do not know which operating system your application may run on, you are probably better off using pip freeze as suggested in other answers here.


回答 7

我认为最好的办法是在存储库文件夹内的路径中安装虚拟环境,最好使用专用于该环境的子目录(当我在存储库根目录中强制安装虚拟环境时,我意外删除了我的整个项目)文件夹,好是我已将项目保存在最新版本的Github中)。

自动安装程序或文档都应将virtualenv路径指示为相对路径,这样,与他人共享项目时,您就不会遇到问题。关于软件包,使用的软件包应通过保存pip freeze -r requirements.txt

I think is that the best is to install the virtual environment in a path inside the repository folder, maybe is better inclusive to use a subdirectory dedicated to the environment (I have deleted accidentally my entire project when force installing a virtual environment in the repository root folder, good that I had the project saved in its latest version in Github).

Either the automated installer, or the documentation should indicate the virtualenv path as a relative path, this way you won’t run into problems when sharing the project with other people. About the packages, the packages used should be saved by pip freeze -r requirements.txt.


回答 8

如果您只是设置开发环境,请使用pip冻结文件,因为caz可以使git repo变得干净。

然后,如果要进行生产部署,则签入整个venv文件夹。这将使您的部署更具可重复性,不需要那些libxxx-dev软件包,并避免了Internet问题。

因此,有两个存储库。一个用于您的主要源代码,其中包括requirements.txt。还有一个env存储库,其中包含整个venv文件夹。

If you just setting up development env, then use pip freeze file, caz that makes the git repo clean.

Then if doing production deployment, then checkin the whole venv folder. That will make your deployment more reproducible, not need those libxxx-dev packages, and avoid the internet issues.

So there are two repos. One for your main source code, which includes a requirements.txt. And a env repo, which contains the whole venv folder.