如何为 Windows 在 Docker 桌面上设置 cron 作业?
How to set up a cron job on Docker Desktop for Windows?
我正在尝试 运行 在 Docker Desktop for windows 的 selenium 容器中执行 cron 作业。因为我认为我 运行 遇到了几个问题,所以我很难弄清楚哪些细节很重要,所以我会尽量做到全面。
环境:
- Docker Windows 的桌面(为了避免行结束问题,我在 Docker 文件中制作了 cron 字符串)
- Selenium-Chrome(需要注意的是大多数东西在 seluser 而不是 root 下 运行 这里。我这么说是因为其他一些解决方案因此不起作用)
问题:
我不能 运行 python 我的 cron 作业
我检查过的相关堆栈溢出链接:
有很多,但 是主要的。
例如,此代码段记录到适当显示的日志文件中:
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
但事实并非如此:
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
在您的 RUN
命令中,整个命令和嵌入的 Python 脚本中都有双引号。 shell 消耗了这些引号对,因此 Python 片段中根本没有引号。
您可以通过对任何一对引号使用单引号,或通过反斜杠转义双引号字符串中的双引号来解决此问题。所有这些都有效:
RUN echo "... print(\"Hello world\") ..." | crontab
RUN echo "... print('Hello world') ..." | crontab
# NB: will not expand environment variables inside the string
RUN echo '... print("Hello world") ...' | crontab
带有 echo
的第一种形式似乎有效,因为 echo "Hello world"
、echo Hello world
和 echo "Hello" "world"
都打印出相同的字符串;它是一个参数还是两个参数并不重要, echo(1) 本身永远不会看到双引号。但是,在 Python 的情况下,您需要将双引号传递给解释器。
如果您面临这样的挑战,通常最好的方法是将嵌入式脚本分解到一个单独的文件中。
#!/usr/bin/env python3
# greet.py
if __name__ == '__main__':
print('Hello world')
那么你的 cron 作业就可以 运行 脚本。
RUN echo '* * * * * /home/seluser/greet.py >> /home/seluser/cron.log' | crontab
我在示例中省略了 sudo
。在 Docker 文件中,您通常已经 运行 成为 root,或者您可以指定 USER root
切换到 root。 sudo
在脚本中使用起来很棘手,并且往往会导致 Docker.
中不必要和不安全的配置
最终的 Docker 文件可能如下所示:
FROM selenium/standalone-chrome
# Install OS packages _before_ copying any application code in.
# This avoids an expensive reinstallation on rebuild.
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --assume-yes --no-install-recommends \
cron
# Now copy your own code in. (Rebuilds will start here, if anything
# in the source tree has changed.)
COPY . /home/seluser
# Set up the cron environment.
RUN echo '* * * * * /home/seluser/greet.py >> /home/seluser/cron.log' | crontab \
&& touch /home/seluser/cron.log
# Declare the main container command. (Actually run the cron daemon;
# don't make the container process be tail(1) with cron being an
# unmonitored side effect.)
CMD ["cron", "-f"]
我正在尝试 运行 在 Docker Desktop for windows 的 selenium 容器中执行 cron 作业。因为我认为我 运行 遇到了几个问题,所以我很难弄清楚哪些细节很重要,所以我会尽量做到全面。
环境:
- Docker Windows 的桌面(为了避免行结束问题,我在 Docker 文件中制作了 cron 字符串)
- Selenium-Chrome(需要注意的是大多数东西在 seluser 而不是 root 下 运行 这里。我这么说是因为其他一些解决方案因此不起作用)
问题:
我不能 运行 python 我的 cron 作业
我检查过的相关堆栈溢出链接:
有很多,但
例如,此代码段记录到适当显示的日志文件中:
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
但事实并非如此:
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
在您的 RUN
命令中,整个命令和嵌入的 Python 脚本中都有双引号。 shell 消耗了这些引号对,因此 Python 片段中根本没有引号。
您可以通过对任何一对引号使用单引号,或通过反斜杠转义双引号字符串中的双引号来解决此问题。所有这些都有效:
RUN echo "... print(\"Hello world\") ..." | crontab
RUN echo "... print('Hello world') ..." | crontab
# NB: will not expand environment variables inside the string
RUN echo '... print("Hello world") ...' | crontab
带有 echo
的第一种形式似乎有效,因为 echo "Hello world"
、echo Hello world
和 echo "Hello" "world"
都打印出相同的字符串;它是一个参数还是两个参数并不重要, echo(1) 本身永远不会看到双引号。但是,在 Python 的情况下,您需要将双引号传递给解释器。
如果您面临这样的挑战,通常最好的方法是将嵌入式脚本分解到一个单独的文件中。
#!/usr/bin/env python3
# greet.py
if __name__ == '__main__':
print('Hello world')
那么你的 cron 作业就可以 运行 脚本。
RUN echo '* * * * * /home/seluser/greet.py >> /home/seluser/cron.log' | crontab
我在示例中省略了 sudo
。在 Docker 文件中,您通常已经 运行 成为 root,或者您可以指定 USER root
切换到 root。 sudo
在脚本中使用起来很棘手,并且往往会导致 Docker.
最终的 Docker 文件可能如下所示:
FROM selenium/standalone-chrome
# Install OS packages _before_ copying any application code in.
# This avoids an expensive reinstallation on rebuild.
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --assume-yes --no-install-recommends \
cron
# Now copy your own code in. (Rebuilds will start here, if anything
# in the source tree has changed.)
COPY . /home/seluser
# Set up the cron environment.
RUN echo '* * * * * /home/seluser/greet.py >> /home/seluser/cron.log' | crontab \
&& touch /home/seluser/cron.log
# Declare the main container command. (Actually run the cron daemon;
# don't make the container process be tail(1) with cron being an
# unmonitored side effect.)
CMD ["cron", "-f"]