I'm trying to run a cron job in a selenium container in Docker Desktop for windows. Because I think I'm running into several problems, it's hard for me to figure out which details matter so I'll try to be as thorough as possible.
Environment:
- Docker Desktop for Windows (to avoid line ending problems I make the cron string in the Dockerfile)
- Selenium-Chrome (one thing to note is that most things are run under seluser instead of root here. I say that because some of the other solutions don't work because of this)
Problem:
I cannot run python in my cron job
Related stack overflow links I've checked:
There are a lot but this is the main one.
For example, this snippet logs to the log file shown appropriately:
FROM selenium/standalone-chrome
COPY . /home/seluser/
# # install selenium
RUN echo "**** install packages ****" && \
sudo apt-get update && \
sudo apt-get install -y cron && \
echo "**** cleanup ****" && \
sudo apt-get clean && \
sudo rm -rf \
/tmp/* \
/var/lib/apt/lists/* \
/var/tmp/*
# Create the log file to be able to run tail
RUN touch /home/seluser/cron.log
# Setup cron job
RUN echo "* * * * * echo "Hello, World!" >> /home/seluser/cron.log" | sudo crontab
# Run the command on container startup
CMD sudo cron && tail -f /home/seluser/cron.log
But this doesn't:
FROM selenium/standalone-chrome
COPY . /home/seluser/
# # install selenium
RUN echo "**** install packages ****" && \
sudo apt-get update && \
sudo apt-get install -y cron && \
echo "**** cleanup ****" && \
sudo apt-get clean && \
sudo rm -rf \
/tmp/* \
/var/lib/apt/lists/* \
/var/tmp/*
# Create the log file to be able to run tail
RUN touch /home/seluser/cron.log
# Setup cron job
RUN echo "* * * * * /usr/bin/python3 -c print("Hello world") >> /home/seluser/cron.log" | sudo crontab
# Run the command on container startup
CMD sudo cron && tail -f /home/seluser/cron.log
In your
RUN
command, you have both double quotes surrounding the entire command and also double quotes in the embedded Python script. The shell consumes these pairs of quotes, and so there are no quotes in the Python fragment at all.You can work around this by using single quotes for either pair of quotes, or by backslash-escaping the double quotes within the double-quoted string. All of these will work:
The first form with
echo
appears to work becauseecho "Hello world"
,echo Hello world
, andecho "Hello" "world"
all print out the same string; it doesn't matter whether it's one or two parameters, and echo(1) itself never sees the double quotes. In the Python case, though, you need to pass the double quotes into the interpreter.If you're facing challenges like this, often the best approach is to break out the embedded script into a separate file.
Then your cron job can just run the script.
I've omitted
sudo
in my examples. In a Dockerfile you are generally running as root already, or you can specifyUSER root
to switch to root.sudo
is tricky to use in scripts and tends to lead to unnecessary and insecure configuration in Docker.A final Dockerfile for this might look like: