如何从Cron作业访问Docker set Environment Variables

Fab*_*ger 40 cron environment-variables docker

我最近尝试从链接的docker容器中运行一个cron作业并遇到问题.我的主docker容器链接到postgres容器,其端口号在创建容器时由docker设置为环境变量.此环境变量未在〜/ .profile或运行我的cron作业时可以加载的任何其他源文件中设置.那我怎样才能从我的cron作业中访问这些环境变量?

谢谢!

Tim*_*ben 44

我遇到了同样的问题.我有一个运行cron的docker容器,可以定期执行一些shell脚本.当我在容器内手动执行它们时,我也很难找到为什么我的脚本运行正常.我尝试了创建一个首先运行以设置环境的shell脚本的所有技巧,但它们从来没有为我工作(很可能我做错了).但是我继续寻找并找到了它,它确实有效.

  1. 为cron容器设置启动或入口点shell脚本
  2. 将此作为第一行执行 printenv | grep -v "no_proxy" >> /etc/environment

这里的诀窍是/etc/environment文件.当容器构建成文件为空时,我是故意的.我在cron(8)的手册页中找到了对该文件的引用.在查看了cron的所有版本之后,他们都会找到一个/etc/?可用于将环境变量提供给子进程的文件.

另外,请注意我创建了我的docker容器以在前台运行cron cron -f.这有助于我避免tail运行以保持容器的其他技巧.

这是我的entrypoint.sh文件供参考,我的容器是debian:jessie基本图像.

printenv | grep -v "no_proxy" >> /etc/environment

cron -f
Run Code Online (Sandbox Code Playgroud)

此外,这个技巧甚至适用于在docker run命令期间设置的环境变量.

  • printenv>/etc/environment是我在4天后尝试各种选项时唯一有用的东西!谢谢! (2认同)
  • 注意使用`/ etc/environment`文件的限制,因为没有可能逃避注释符号##,所以你不能在变量的值中使用它... (2认同)
  • 可能值得注意的是`... | grep -v " no_proxy` 部分特定于某些环境,对于大多数人来说这只是一个转移注意力的事情。正如 @Deko 所说,对于大多数情况来说,魔法只是 `printenv > /etc/environment`。(另外,使用“>>”会附加到任何现有的 /etc/environment 文件,但我从未见过一个不为空的文件。有人有不同的经历吗??) (2认同)
  • 请注意 `>>` 将导致添加 cron 行的次数与 docker 容器重新启动的次数一样多,最好只是 `>` (2认同)

Ale*_*lov 16

我建议使用declare导出您的环境并避免转义问题(使用CMD或ENTRYPOINT或直接在其中一个可能调用的包装脚本中):

declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env

Grep -v负责过滤掉只读变量.

您可以稍后轻松加载此环境,如下所示:

SHELL=/bin/bash
BASH_ENV=/container.env
* * * * * root /test-cron.sh
Run Code Online (Sandbox Code Playgroud)

  • 我认为这也是正确的答案,但我没有使用“grep”的“-v”,我更喜欢放置我将使用的特定变量,如下所示:`declare -p | grep -E 'VAR1|VAR2|VAR3|ETC' > /container.env` (2认同)
  • Alex Fedulov 的正则表达式太贪婪了。它将过滤掉超出预期的变量声明(例如,它会过滤掉名为“FLUID”的变量)。我建议使用表达式 `declare -p | grep -Ev '^declare -[[:alpha:]]*r'` 应该过滤掉所有只读声明。 (2认同)
  • @TomášPospíšek 或者修改模式以尊重单词边界?:`grep -Ev '\b(BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID)\b'`,甚至`'\b(BASHOPTS|BASH_VERSINFO|EUID |PPID|SHELLOPTS|UID)='` (2认同)

小智 6

通过使用包装 shell 脚本运行 cron 守护进程,可以将系统环境变量附加到 crontab 文件的顶部。以下示例来自 CentOs 7,

在 Dockerfile 中

COPY my_cron /tmp/my_cron
COPY bin/run-crond.sh run-crond.sh
RUN chmod -v +x /run-crond.sh
CMD ["/run-crond.sh"]
Run Code Online (Sandbox Code Playgroud)

运行_cron.sh:

#!/bin/bash

# prepend application environment variables to crontab
env | egrep '^MY_VAR' | cat - /tmp/my_cron > /etc/cron.d/my_cron

# Run cron deamon
# -m off : sending mail is off 
# tail makes the output to cron.log viewable with the $(docker logs container_id) command
/usr/sbin/crond -m off  && tail -f /var/log/cron.log
Run Code Online (Sandbox Code Playgroud)

这是基于某个地方的一篇很棒的博客文章,但我丢失了链接。


Ond*_*zko 6

受到@Kannan Kumarasamy 回答的启发:

  for variable_value in $(cat /proc/1/environ | sed 's/\x00/\n/g'); do
    export $variable_value
  done
Run Code Online (Sandbox Code Playgroud)

我无法确定 pid1 是什么进程,并且它在操作系统的生命周期内保持稳定。但由于它是第一个要运行的进程,在容器内我想我们可以理所当然地认为它是一个设置了所需环境变量的进程。除非一些 linux/docker 文档证明这完全没问题,否则请对所有这些都持怀疑态度。


Kan*_*amy 5

您可以运行以下命令

. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/1/environ)
Run Code Online (Sandbox Code Playgroud)

当您的环境变量具有特殊字符(例如' " =