【问题标题】:Why does venv break after rsync?为什么 venv 在 rsync 之后会中断?
【发布时间】:2019-08-13 19:03:22
【问题描述】:

我正在尝试为我的 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...

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

当我在目标服务器上激活 venv 并运行 which python3 时,我得到了不正确的 /usr/bin/python3

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

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

【问题讨论】:

标签: python python-3.x continuous-integration rsync python-venv


【解决方案1】:

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

因此,环境仅在主机上有效路径venv已执行。文档中也说明了这一点(省略了某些部分):

运行此命令会创建目标目录 [...] 并在其中放置一个 pyvenv.cfg 文件,其中的 home 键指向 Python 运行该命令的安装。它还创建一个 bin [...] 子目录,其中包含 Python 二进制文件/二进制文件的副本/符号链接(根据平台或环境创建时使用的参数)。

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

mkdir /tmp/example_dir_for_stackoverflow
cd /tmp/example_dir_for_stackoverflow
python3 -m venv venv
grep stackoverflow venv/bin/activate

它会输出:

VIRTUAL_ENV="/tmp/example_dir_for_stackoverflow/venv"

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

【讨论】:

  • 感谢您的回答。我以为我已经复制了相同的目录结构,但问题可能是它是不同的 Python 安装。 Python 版本相同,都是 3.6.8,但问题可能出在您提到的那些符号链接上。再次感谢您的宝贵时间。
【解决方案2】:

在我看来,最好的办法是从 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 之前)。与上述 sn-p 的前 5 行相同。

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

现在您已经在远程主机上完成了设置,让我们回到您开发的主机 1。 您需要同步您的 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

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

对粗体问题的“严格”回答

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多