当前,我们在构建服务器上构建应用程序,在该服务器上使用virtualenv命令创建虚拟环境,将所有Python依赖项安装到其中,然后使用以下bash命令对其进行“修补”以使其可重定位:

# Adopt virtualenv to the target system
echo "* Patching virtual envirinment for target system"
for f in "${VENV_PATH}/bin"/* ; do
    if [ -n "$(file "${f}" | grep "text")" ] ; then
    echo "  + ${f}"
        sed -i "s;"${VENV_PATH}";/path/to/the/target/directory/venv;" "${f}"
    fi
done
rm -rf "${VENV_PATH}/lib64"
ln -s "/path/to/the/target/directory/venv/lib" "${VENV_PATH}/lib64"


然后,我们将其打包到包含应用程序其他部分的RPM软件包中,部署到多个目标服务器并通过yum进行安装。

使虚拟环境可重定位是“一次构建,多次部署”-换句话说,是避免在所有目标服务器上安装相同的依赖项。

问题在于,该修补脚本看上去确实脆弱,据我所知,这与当前的Python版本紧密相关,并且还要求构建服务器与目标服务器使用相同的操作系统(或至少使所有与python相关的路径都匹配) )。

我的理解正确吗?在每个目标上重建虚拟环境会更好吗? (我们可以使用pip或缓存来加快pip-accel的安装命令)解决此问题的一般方法是什么?

评论

不幸的是,virtualenv的--relocatable标志永远无法正常工作,如此处所述virtualenv.pypa.io/en/stable/userguide / ...如果项目发现它很脆弱,我敢打赌,这也将对您有用。 deb有dh-virtualenv,但我不知道rpm,但是点冻结和转盘怎么样? pip wheel --wheel-dir =。/ artifacts -r requirements.txt将./artifacts打包到您的RP​​M中,创建并激活venv然后运行pip install ./artifacts/我们将轮子推入gcp存储桶中,然后添加网址用于通过jenkins构建。

#1 楼


解决此问题的一般方法是什么?


解决问题的理想方法是对应用程序进行Docker化,因为它将消除对兼容性的任何担忧在构建服务器和运行服务器之间。在Dockerfile中使用pip安装依赖项很简单,而且只要您部署相同的容器映像,就不必担心不一致。

编辑:很幸运,我实际上发现自己想要有一个既可以在Docker内部也可以在Docker外部工作的venv,所以我想出了以下内容:

python3.6 -m venv --copies venv
sed -i '43s/.*/VIRTUAL_ENV="$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}" )")" \&\& pwd)"/' venv/bin/activate
sed -i '1s/.*/#!\/usr\/bin\/env python/' venv/bin/pip*