How can I access Docker set Environment Variables From a Cron Job
I've recently tried running a cron job from within a linked docker container and run into an issue. My main docker container is linked to a postgres container and its port number is set as an environment variable by docker upon the containers creation. This environment variable is not set in ~/.profile or any other source file that I could load when running my cron job. How can I then access these environment variables from my cron job?
Thanks!
Solution 1:
I ran into this same problem. I have a docker container that runs cron to execute some shell scripts periodically. I too had a hard time finding out why my scripts would run fine when I manually executed them inside the container. I tried all the tricks of creating a shell script that would run first to set the environment, but they never worked for me (most likely I did something wrong). But I continued looking and found this and it does work.
- Setup a start or entry point shell script for your cron container
- Make this the first line to execute
printenv | grep -v "no_proxy" >> /etc/environment
The trick here is the /etc/environment
file. When the container is built that file is empty, I think on purpose. I found a reference to this file in the man pages for cron(8). After looking at all the versions of cron they all elude to an /etc/?
file that you can use to feed environment variables to child processes.
Also, note that I created my docker container to run cron in the foreground, cron -f
. This helped me avoid other tricks with tail
running to keep the container up.
Here is my entrypoint.sh file for reference and my container is a debian:jessie base image.
printenv | grep -v "no_proxy" >> /etc/environment
cron -f
Also, this trick worked even with environment variables that are set during, docker run
commands.
Solution 2:
I would recommend using declare
to export your environment and avoid escaping issues. Can be used in CMD or ENTRYPOINT or directly in a wrapper script which might be called by one of them:
declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env
Grep -v takes care of filtering out read-only variables.
You can later easily load this environment like this:
SHELL=/bin/bash
BASH_ENV=/container.env
* * * * * root /test-cron.sh