【问题标题】:How to set up a cron job on Docker Desktop for Windows?如何在 Docker Desktop for Windows 上设置 cron 作业?
【发布时间】:2021-09-05 22:57:24
【问题描述】:

我正在尝试在 Windows 的 Docker Desktop 中的 selenium 容器中运行 cron 作业。因为我觉得我遇到了几个问题,所以我很难弄清楚哪些细节很重要,所以我会尽量做到彻底。

环境:

  1. Docker Desktop for Windows(为了避免行尾问题,我在 Dockerfile 中创建了 cron 字符串)
  2. Selenium-Chrome(需要注意的一点是,这里大多数东西都是在 seluser 下而不是 root 下运行的。我这么说是因为其他一些解决方案因此不起作用)

问题:

我无法在我的 cron 作业中运行 python

我检查过的相关堆栈溢出链接:

有很多,但this是主要的。

例如,这个 sn-p 记录到适当显示的日志文件:

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

【问题讨论】:

  • print( 之后和Hello 之前的双引号匹配echo 行开头的双引号,所以它会丢失;您没有完整有效的单 shell 字 Python 脚本。最好COPY 一个独立的可运行脚本并运行它,而不是尝试使引用工作。 (你也根本不需要sudo;你可以在需要的地方切换到USER root。)
  • 对于您的第一部分,为什么 echo 脚本会起作用?它有同样的双引号问题。至于 COPY 解决方案,即使仅使用 echo 语句,我也无法找到使其工作的方法。链接的解决方案在 Windows 上不起作用。
  • 引用恰好与echo 配合使用;它并不关心它有多少参数。在echo 的情况下,您可能会查看实际创建的 crontab;我不希望它有任何"..."
  • @DavidMaze 一年后我知道了...但是如果您愿意,您可以从您的 cmets 中创建一个答案,我会将其标记为已接受,因为它帮助我找出了我的问题。

标签: docker cron docker-desktop


【解决方案1】:

在您的 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 worldecho "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。在 Dockerfile 中,您通常已经以 root 身份运行,或者您可以指定 USER root 以切换到 root。 sudo 在脚本中使用起来很棘手,并且往往会导致在 Docker 中进行不必要且不安全的配置。

最终的 Dockerfile 可能如下所示:

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"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 2023-03-29
    • 2018-04-09
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多