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

问题描述 投票:34回答:6

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

谢谢!

cron environment-variables docker
6个回答
41
投票

我遇到了同样的问题。我有一个运行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

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


14
投票

我建议使用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

3
投票

可以使用包装器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"]

润_cron.是:

#!/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

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


2
投票

环境已设置,但cron作业无法使用。要解决这个问题,你可以做这两件简单的事情

1)将env保存到ENTRYPOINT或CMD中的文件中

CMD env > /tmp/.MyApp.env && /bin/MyApp

2)然后将env读入你的cron命令,如下所示:

0 5 * * * . /tmp/.MyApp.env; /bin/MyApp

0
投票

为了逃避任何可能破坏你的脚本的怪异角色,并根据Mark's answer的推理,将这一行添加到你的entrypoint.sh

env | sed -r "s/'/\\\'/gm" | sed -r "s/^([^=]+=)(.*)\$/\1'\2'/gm" \ > /etc/environment

这样,如果你有像affinity:container==My container's friend这样的变量,它将被转换为affinity:container='=My container\'s friend,依此类推。


0
投票

您可以运行以下命令

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

当您拥有包含' " =等特殊字符的环境变量时,此功能非常有用

© www.soinside.com 2019 - 2024. All rights reserved.