Django 和 VirtualEnv 开发/部署最佳实践
我很好奇大家是怎么把自己的Django项目和虚拟环境(virtualenv)一起部署的。
- 更具体一点,你们是怎么确保生产环境的虚拟环境和开发机器上的虚拟环境保持一致的呢?
我用git来管理代码,但我的虚拟环境并不在git仓库里——我应该把它放进去吗?还是说最好是用pip freeze命令,然后在服务器上根据这个输出重新创建环境?(如果你这样做的话,能不能描述一下步骤?我发现关于如何“解冻”的文档很少——像pip install -r freeze_output.txt
这样的命令可以用吗?)
2 个回答
我使用这个bootstrap.py:http://github.com/ccnmtl/ccnmtldjango/blob/master/ccnmtldjango/template/bootstrap.py
它需要一个叫做'requirements'的文件夹,结构大概是这样的:http://github.com/ccnmtl/ccnmtldjango/tree/master/ccnmtldjango/template/requirements/
里面有一个apps.txt和一个libs.txt(apps.txt里包含了一些内容——我只是喜欢把django应用和其他python模块分开),还有一个src文件夹,里面放着实际的压缩包。
当运行./bootstrap.py时,它会创建一个虚拟环境(如果之前有的话会把它清除掉),并把requirements/apps.txt里的所有内容安装到这个环境里。我不会在虚拟环境里安装其他东西。如果我想添加一个新的库,我会把压缩包放到requirements/src/里,往其中一个文本文件里加一行,然后重新运行./bootstrap.py。
bootstrap.py和requirements会被放进版本控制里(还有一个pip.py的副本,这样我就不需要在系统范围内安装它)。虚拟环境本身不会被放进版本控制。每次我推送到生产环境时,我的脚本都会在生产服务器上运行./bootstrap.py。(bootstrap.py还特别注意要使用Python 2.5,因为我们的生产服务器(Ubuntu Hardy)上就是这个版本,而我的开发机器(Ubuntu Karmic)如果不小心默认会用Python 2.6)
我最近在工作中设置了类似的东西,使用了pip、Fabric和git。整个流程大致是这样的,参考了这个脚本:
- 在我们的源代码目录中,我们维护一个requirements.txt文件。这个文件我们会手动管理。
- 当我们发布新版本时,Fabric脚本会根据我们传入的版本信息创建一个压缩包。
- Fabric会通过命令
git log -1 --format=format:%h TREEISH
找到我们要部署的版本的SHA值。这个值就是SHA_OF_THE_RELEASE
。 - Fabric会用命令
git log -1 --format=format:%h SHA_OF_THE_RELEASE requirements.txt
获取我们requirements文件的最后一个SHA值。这个命令会输出一个简短的哈希值,比如1d02afc
,这是这个特定版本的文件的SHA。 - 然后,Fabric脚本会查看远程主机上存储虚拟环境的目录。
- 如果没有名为
1d02afc
的目录,就会创建一个新的虚拟环境,并用命令pip install -E /path/to/venv/1d02afc -r /path/to/requirements.txt
进行设置。 - 如果已经存在
path/to/venv/1d02afc
,那么就什么都不做。
- 如果没有名为
这个过程的关键在于将你想要的版本信息传递给git,并让它进行打包(通过Fabric)。通过使用git archive my-branch
、git archive 1d02afc
或其他命令,我可以确保在远程机器上安装正确的包。
我选择这个方法是因为我不想在版本之间如果包没有变化的情况下,留下多余的虚拟环境。我也不喜欢把我依赖的实际包放在自己的源代码目录中。