为什么 venv 在 rsync 后中断?

Why does venv break after rsync?

我正在尝试为我的 Python 脚本和应用程序构建一个 CI/CD 进程。我能够在测试容器中构建我的 venv,但是当我将它同步到目标服务器时,Python 的版本似乎中断了。这就是我正在尝试的:

- cp -a ./. $APP_DIR
- cd $APP_DIR
- python3 -m venv venv
- source venv/bin/activate
- pip3 install -r requirements.txt
...
- rsync...

所有涉及的环境都是运行ning Python 3.6.8

当我在目标服务器上激活 venv 并且 运行 which python3 我得到 /usr/bin/python3 这是不正确的。

为什么?为什么 venv 在通过 rsync 部署到服务器时会中断?

我是 Python 开发和虚拟环境流程的新手。 venv 是否应该只在他们需要 运行 的服务器(或容器)上创建?有时我的目标服务器上没有安装 python3-venv。是否可以使用代码部署 venv 并将其用于 运行 我的脚本?

通过venv创建环境时,它将环境路径的绝对路径存储到bin/activate中。此外,在指向现有 python 安装的新环境中创建了一些符号链接。

因此,环境仅在主机 路径 venv 上有效。文档中也有说明(部分省略):

Running this command creates the target directory [...] and places a pyvenv.cfg file in it with a home key pointing to the Python installation from which the command was run. It also creates a bin [...] subdirectory containing a copy/symlink of the Python binary/binaries (as appropriate for the platform or arguments used at environment creation time).

您可以通过以下命令轻松检查此事实:

mkdir /tmp/example_dir_for_Whosebug
cd /tmp/example_dir_for_Whosebug
python3 -m venv venv
grep Whosebug venv/bin/activate

它将输出:

VIRTUAL_ENV="/tmp/example_dir_for_Whosebug/venv"

如果您将此环境同步到另一个系统到不同的路径 and/or 不同的 python 安装,bin/activate 中的设置不匹配并且不起作用。

在我看来,你最好的选择是使用

从 rsync 中排除 venv 文件夹
rsync --exclude 'venv'  source/ destination/

requirements.txt 文件是您最好的朋友,可以让您的依赖项在任何地方都得到满足。

如果您对所提供的 Python 版本感到满意,我还建议您从 Linux 发行版中安装 python3-venv 软件包。否则安装另一个 Python 版本(您会在 Internet 上找到如何为您的发行版安装不同的 Python)。

举例:

Host 1(这是你开发的地方,你可以在你的venv中添加一些东西)

cd /tmp/
mkdir app_base # base folder for venv/ and app_code/
cd app_base/
mkdir app_code # base folder for code only

# LOCAL virtual environment creation and activatin
python3 -m venv venv
source venv/bin/activate

# Just an example of whatever you may need
pip install numpy
# Let's say that it could be enough for your app to work.

# Create requirements.txt
pip3 freeze >requirements.txt

服务器,容器,任何远程..

设置 这应该 运行 一次(或至少 rsync 之前)。与上述代码段的前 5 行相同。

cd /tmp/
mkdir app_base
cd app_base/
mkdir app_code
python3 -m venv venv

现在您已经在远程主机上完成了设置,让我们return到您开发的主机 1。 您需要 rsync 您的 app_coderequirements.txt(可能还有其他一些东西),但不是 venv 文件夹

主机 1

您可以将其包装在 cron 作业中

rsync -xav -e ssh --exclude 'venv' /tmp/app_base/ user@X.X.X.X:/tmp/app_base/

然后,最后,您可以让您的服务器虚拟环境满足您的需要,直接 运行在服务器上安装它。

服务器,容器,任何远程..

cd /tmp/app_base
source venv/bin/activate
pip3 install -r requirements.txt

现在,在远程主机上,您应该能够运行(单元测试)您的代码。

'strict' 对您加粗问题的回答

Why? Why does venv break when deployed to a server via rsync?

是:一些 Python 包(比如我在示例中使用的 numpy)出于性能原因提供二进制例程。复制虚拟环境文件夹仅适用于相同的 Linux 发行版或 Windows 版本,具有相同的体系结构和 Python 版本。这不是创建虚拟环境的目的。