在我的git存储库中有我的virtualenv目录不好吗?

我在考虑把virtualenv的Django web应用程序,我正在我的应用程序的git存储库。这似乎是一个简单的方法来保持部署的简单和容易。有什么理由不让我这么做吗?

165801 次浏览

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

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

我使用pip freeze获取我需要的包到一个requirements.txt文件中,并将其添加到我的存储库中。我试图想出一种方法来解释为什么要存储整个virtualenv,但我找不到。

我以前也这样做,直到我开始使用根据环境不同而编译的库,比如PyCrypto。我的PyCrypto mac无法在Cygwin上运行,也无法在Ubuntu上运行。

管理存储库完全是一场噩梦。

无论哪种方式,我都发现更容易控制自己的神经冻结。一个需求文件,而不是把它全部放在git中。它也更干净,因为你可以避免在这些库更新时提交数千个文件的垃圾邮件……

将virtualenv目录存储在git中,就像你提到的,允许你通过做一个git克隆(加上安装和配置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克隆或git拉之后运行的shell脚本中。

存储virtualenv目录还使处理pip升级变得有点棘手,因为您必须手动添加/删除和提交升级产生的文件。对于requirements.txt文件,只需更改requirements.txt中适当的行,然后重新运行pip install -r requirements.txt。如前所述,这也减少了“提交垃圾邮件”。

如果你只是设置开发环境,然后使用pip冻结文件,caz,使git回购干净。

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

所以有两个回购。一个用于您的主要源代码,其中包括一个requirements.txt。和一个env repo,其中包含整个venv文件夹。

我使用了基本上是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(安静)选项,在python3不可用时使用python,等等。

然后,它可以从任何当前工作目录中获取,并将正确激活,如果需要,首先设置虚拟环境。我的顶级测试脚本通常有这样的代码,所以它可以在不需要开发人员激活的情况下运行:

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

./activate而不是activate在这里很重要,因为后者会在找到当前目录中的activate之前在你的路径中找到任何其他activate

在回购中包含任何依赖于环境的组件或设置并不是一个好主意,因为使用回购的关键方面之一可能是与其他开发人员共享它。下面是我如何在Windows PC(比如Win10)上设置我的开发环境。

  1. 打开Pycharm,在第一页,选择从源代码控制系统中检查项目(在我的情况下,我使用github)

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

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

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

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

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

好处:如果你想让人们很容易(好吧,几乎很容易)安装你的软件所需的所有库,你可以使用

pip freeze > requirements.txt

并将该指令放在git中,以便人们可以使用以下命令一次性下载所有所需的库。

pip install -r requirements.txt

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

无论是自动安装程序还是文档都应该将virtualenv路径指示为相对路径,这样在与其他人共享项目时就不会遇到问题。关于包,使用的包应该保存在pip freeze -r requirements.txt中。