如何在 cron 任务中访问 Docker 容器的环境变量?

cron 守护进程不读取容器启动时的环境变量,常见解法:启动脚本把 env 导出到文件(env > /etc/environment)让 cron 源它,或用 docker run -e 显式传入。本文给出可靠做法。

最佳实践
如何在 cron 任务中访问 Docker 容器的环境变量?封面

问题本质:容器启动时通过 docker run -e 传入的环境变量只对 PID 1 进程生效;容器内另起的 cron 守护进程不继承这些变量**,所以 cron 任务里取不到。最常用解法:容器启动脚本把当前环境导出到文件(printenv > /etc/environment),cron 任务执行前先 source 它。**

症状

docker run -e DB_HOST=mysql myapp

容器里 echo $DB_HOST 有值,但 cron 任务里同样的变量是空的——cron 以最小环境启动任务。

解法一:导出环境到文件(推荐)

容器入口脚本(entrypoint)里加一行:

#!/bin/bash
printenv | grep -v 'no_proxy' > /etc/environment
cron -f   # 或 exec 主进程,cron 后台

cron 任务里先加载:

* * * * * . /etc/environment; /app/backup.sh >> /var/log/backup.log 2>&1

解法二:crontab 里写死变量

直接在 crontab 顶部声明:

DB_HOST=mysql
DB_PASS=secret
0 3 * * * /app/backup.sh

适合变量少且固定的场景;变量来自编排系统时不适用。

解法三:任务命令里显式注入

0 3 * * * /usr/bin/env DB_HOST=mysql /app/backup.sh

解法四:让 PID 1 调度,绕开 cron

容器最佳实践倾向单进程。定时任务改用:

  • K8s CronJob:每个任务独立 Pod,环境变量天然注入
  • 应用内调度器:APScheduler(Python)、node-cron 等,进程内调度直接用进程环境
  • 宿主机 cron 调 docker execdocker exec myapp /app/backup.sh,exec 会带上容器主进程的环境

观测云对照

定时任务跑没跑、成没成,要有监控。 无论哪种方案,任务日志集中采集到观测云后,用监控器对"预期时间点未产生日志/出现错误关键字"做告警,避免 cron 静默失效。

常见问题(FAQ)

Q:为什么 docker exec 里能拿到变量而 cron 不行?
A:docker exec 会继承容器主进程的环境;cron 是独立守护进程,环境自己造。

Q:/etc/profile.d/ 里的脚本 cron 会读吗?
A:不会。cron 不跑登录 shell,profile 系列文件都不生效。

Q:变量保密怎么处理的?
A:不要写进 crontab 明文;用 K8s Secret + CronJob,或 entrypoint 从密管系统拉取后写 /etc/environment(注意文件权限 600)。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台