从 Azure Web 应用服务器上的 cron 任务的虚拟环境加载变量

Load variables from a virtual env for a cron task on Azure web app server

提问人:Mathieu 提问时间:11/16/2023 最后编辑:Mathieu 更新时间:11/19/2023 访问量:36

问:

我有一个在 Azure 应用服务上运行的 python (Django) Web 应用。

尽管我从其他 SO 线程尝试了一切,但我无法弄清楚如何从我的 cron 任务访问环境变量。这可能是由于 Azure 如何将 复制到一个奇怪的.稍后会详细介绍。venvantenv

真正想要的是在 cron 中使用 Django 命令,比如 .但是,我很快意识到 Django 虚拟环境没有在 cron 中正确加载。所以我决定一步一步来,看看如何从 cron 访问虚拟环境。./manage.py some_command

我试过什么

初步实施

我正在使用 Azure 应用服务 SSH 控制台测试我的设置,该控制台位于 。https://{my-app-name}.scm.azurewebsites.net/webssh/host

脚本

我创建了一个脚本来试水:/home/scripts/log-env.sh

#!/bin/bash
trace=/home/scripts/trace
path=$(...) # Some command that locates the venv directory
echo "src path: ${path}" > ${trace}  # I can see ${path} is set correctly
echo "MY_VAR before source: [${MY_VAR}]" >> ${trace}
source ${path}/antenv/bin/activate; echo "MY_VAR same command line as source: [${MY_VAR}]" >> ${trace}
echo "MY_VAR after source: [${MY_VAR}]" >> ${trace}

输出

当我在终端中运行脚本时,它表明我甚至不需要获取 venv,因为在调用之前可以访问:$MY_VARsource

# Content of trace file /home/scripts/trace when script runs in the terminal
src path: /tmp/8dbe5c185e85419
$MY_VAR before source: [expected_value]
$MY_VAR same command line as source: [expected_value]
$MY_VAR after source: [expected_value]

但是当它从 cron 运行时,无论是在激活 venv 之前还是之后,都不会被访问:$MY_VAR

# Content of trace file /home/scripts/trace when script runs in cron
src path: /tmp/8dbe5c185e85419
$MY_VAR before source: []  # empty
$MY_VAR same command line as source: []  # empty
$MY_VAR after source: []  # empty

克朗

我在crontab中添加了以下条目:

> crontab -l
* * * * * bash /home/scripts/log-env.sh > /home/scripts/cron.log 2>&1

其他尝试

我尝试了以下更改,解决了 SO 上的其他问题,但在我的情况下不起作用:

在 crontab 之上添加:SHELL=/bin/bash

> crontab -l
SHELL=/bin/bash
* * * * * bash /home/scripts/log-env.sh > /home/scripts/cron.log 2>&1

cron 中的源代码

> crontab -l
* * * * * cd /tmp/8dbe5c185e85419 && source /tmp/8dbe5c185e85419/antenv/bin/activate && /home/scripts/log-env.sh > /home/scripts/cron.log 2>&1

Azure 与普通antenv/venv/

出于某种原因,Azure 服务器有一个目录:antenv/

(antenv) root@23e4a05be277:/tmp/8dbe5c185e85419# ls -l *env
antenv:
total 16
drwxr-xr-x 2 root root 4096 Nov 15 16:30 bin
drwxr-xr-x 3 root root 4096 Nov 15 16:30 include
drwxr-xr-x 3 root root 4096 Nov 15 16:30 lib
-rw-r--r-- 1 root root  287 Nov 15 16:30 pyvenv.cfg

venv:
total 20
drwxr-xr-x 2 root root 4096 Nov 15 16:30 bin
drwxr-xr-x 3 root root 4096 Nov 15 16:30 include
drwxr-xr-x 3 root root 4096 Nov 15 16:30 lib
drwxr-xr-x 3 root root 4096 Nov 15 16:30 lib64
-rwxr-xr-x 1 root root  282 Nov 15 16:30 pyvenv.cfg

这是默认设置的环境。它在连接到 SSH 时处于活动状态,如提示中所示的前缀:(antenv)

(antenv) root@23e4a05be277:/tmp/8dbe5c185e85419

这些文件如下所示:pyvenv.cfg

root@23e4a05be277:/tmp/8dbe5c185e85419# cat *env/*.cfg
# antenv/pyvenv.cfg
home = /tmp/oryx/platforms/python/3.11.6/bin
include-system-site-packages = true
version = 3.11.6
executable = /tmp/oryx/platforms/python/3.11.6/bin/python3.11
command = /tmp/oryx/platforms/python/3.11.6/bin/python3.11 -m venv --copies --system-site-packages /tmp/8dbe5c185e85419/antenv

# venv/pyvenv.cfg
home = /opt/hostedtoolcache/Python/3.11.6/x64/bin
include-system-site-packages = false
version = 3.11.6
executable = /opt/hostedtoolcache/Python/3.11.6/x64/bin/python3.11
command = /opt/hostedtoolcache/Python/3.11.6/x64/bin/python -m venv /home/runner/work/jobalerts/jobalerts/venv

我尝试了各种更改以及 .没有一个奏效。antenvvenv

毋庸置疑,我在这里已经超出了我的深度。欢迎对这个烂摊子提供任何帮助。

Django Azure cron azure-web-app-service virtualenv

评论

0赞 Kimonode 11/16/2023
就目前而言,我发现的最不可怕的解决方法是:learn.microsoft.com/en-us/answers/questions/719903/......不过,我不是很喜欢使用。sleep
0赞 Mess 11/16/2023
你可以考虑使用 django-crontab,它运行得很好。
0赞 Kimonode 11/16/2023
@Mess:我在搜索过程中看到了 django-crontab,但它看起来很可疑,因为上次更新是在 5 年前的 2018 年。但我会试一试。谢谢!
0赞 Kimonode 11/18/2023
@Mess,django-crontab 只能编辑 crontab 以从 virtualenv 调用 python 命令。我不知道 Azure 对他们的环境做了什么,但没有标准解决方案有效。

答:

1赞 Kimonode 11/19/2023 #1

正如我在评论中所写的那样,就目前而言,我发现的最不可怕的解决方法是:https://learn.microsoft.com/en-us/answers/questions/719903/how-to-set-my-django-apps-management-commands-as-c

不过,我不是使用睡眠的忠实粉丝。由于计划是我产品的关键部分,因此我将研究 Azure 的替代方案,看看是否可以在那里使用 cron。