将我的virtualenv目录放在我的git存储库中是不是很糟糕?

Lyl*_*att 253 python django virtualenv

我正在考虑将virtualenv用于我在我的应用程序的git存储库中创建的Django Web应用程序.这似乎是保持部署简单易用的简单方法.我有什么理由不这样做吗?

我是virtualenv的新手,所以很有可能这是一个非常愚蠢的问题.

Rya*_*ady 264

我用来pip freeze将我需要的包放到一个requirements.txt文件中并将其添加到我的存储库中.我试着想办法为什么要存储整个virtualenv,但我不能.

  • 您可以在repo中保存不必要的空间,并仍然可以在单个命令中部署到新服务器:virtualenv --no-site-packages --distribute .env && source .env/bin/activate && pip install -r requirements.txt (75认同)
  • 如果你在64位机器上说"pip install mysql-python",然后有32位机器的人试图使用它,它将无法工作.与许多Python模块一样,它使用C模块来提高性能.我想Windows-> Linux也行不通. (11认同)
  • 只是一句话:我们过去得到了一点点因为某些图书馆从pip变得不可用(版本太旧),在网站停机时迫使升级.所以...我现在再也不会依赖'pip freeze`来做到这一点.问题是在强制升级重新部署期间,没有人为此付费,而对于中间升级("最佳实践"维护),没有人会这样做. (7认同)
  • 关于@RayanBrady注释的注释:`--distribute`和`--setuptools`选项现在是no-op.(分发,这是一个setuptools的分支很久以前就被合并了).`--no-site-packages`是DEPRECATED,现在是默认行为 (4认同)
  • 我给你这个问题的答案,因为它可能是“最佳实践”,而你首先提供了它。我肯定遇到了每个人都提到的一些问题。我估计我要花一天的时间弄乱它,然后再做你们一直以来建议的事情,并使用pip和需求文件。谢谢你的帮助! (2认同)

Dav*_*ler 43

正如您所指出的,将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
Run Code Online (Sandbox Code Playgroud)

就个人而言,我只是把它们放在我执行git clone或git pull之后运行的shell脚本中.

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

  • 请注意,现在不推荐使用--distribute(至少在15.1.0中):```--distribute DEPRECATED.仅保留向后兼容性.此选项无效.`` (3认同)

Yuj*_*ita 36

我曾经这样做,直到我开始使用根据环境(如PyCrypto)编译不同的库.我的PyCrypto mac不适用于Cygwin不适用于Ubuntu.

管理存储库变成了一个彻头彻尾的噩梦.

无论哪种方式,我发现管理pip冻结和需求文件比在git中使用它更容易.它也更清洁,因为你可以避免数千个文件的垃圾邮件,因为这些库得到更新...


Tor*_*cht 15

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

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


Wil*_*idi 10

在您的存储库中包含任何依赖于环境的组件或设置作为使用存储库的关键方面之一并不是一个好主意,也许是与其他开发人员共享它。以下是我在 Windows PC(例如 Win10)上设置开发环境的方法。

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

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

  3. 选择位于 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
Run Code Online (Sandbox Code Playgroud)

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

pip install -r requirements.txt 
Run Code Online (Sandbox Code Playgroud)

  • @jbuddy_13 不,从字面上解释这个冻结是有误导性的。 (3认同)

Cur*_*son 5

我基本上使用的是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"
Run Code Online (Sandbox Code Playgroud)

(根据大卫的回答,这假设你正在做一个pip freeze > requirements.txt保持你的需求列表是最新的。)

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

然后可以从任何当前工作目录获取并正确激活,如有必要,首先设置虚拟环境。我的顶级测试脚本通常具有以下代码,以便开发人员无需先激活即可运行它:

cd "$(dirname "$0")"
[[ $VIRTUAL_ENV = $(pwd -P) ]] || . ./activate
Run Code Online (Sandbox Code Playgroud)

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