如何在创建 Docker 容器时向 cron/anacron 添加任务

我试图在我的 Docker 容器中添加一个简单的 cron 任务,并希望它在设置期间添加,以便在 ./launcher rebuild app 完成后自动运行。

当我手动使用 vim 将 cron 任务添加到 /etc/cron.d/anacron 文件时,它可以正常工作。但如果我使用 echo -n '* * * * * root python3 /var/www/discourse/script/email_me.py' >> /etc/cron.d/anacron 这样的命令编辑文件(即不进入并保存文件),cron 似乎没有检测到更改,也不会运行该任务。

如果我随后使用 vim 在文件中任意位置添加一个空格并保存,cron 就会检测到更改并开始运行该任务。

由于使用 echo 命令添加的更改无法被检测到,因此将此命令添加到我的 app.yml 文件中不起作用。

我还尝试在通过 echo 添加更改后执行 docker restart app,但仍然无效。

我觉得应该有一个更简单的方法,只是我还没想到。在设置完成后还需要编辑 anacron 文件,感觉这并不是正确的做法。

您能更详细地解释一下您在这里试图做什么吗?

您很可能会发现,为论坛编写一个在 Sidekiq 中按固定间隔运行的插件要容易得多。

感谢您的回复!也许这样会更清楚:

  • 我正在运行一个私有托管的 Discourse 仓库,其中包含一些自定义文件。
  • 我在 Discourse 的 script 目录下有一个名为 email_me.py 的文件。
  • 运行该文件时,它会向我发送一封主题为“Hello World!”的邮件。
  • 我想在 Discourse Docker 容器中创建一个 cron 任务,每分钟运行一次该文件。
  • 这可以通过使用 vim 等编辑器,手动将行 * * * * * root python3 /var/www/discourse/script/email_me.py 添加到 /etc/cron.d/anacron 文件中来实现。
  • 我希望上述 cron 任务在 Discourse 容器设置时自动运行,但我无法通过 app.yml 文件使用 vim 来完成。
  • 我尝试在 app.yml 文件中将命令 echo -n '* * * * * root python3 /var/www/discourse/script/email_me.py' >> /etc/cron.d/anacron 作为命令执行。这确实成功将行添加到了 anacron 文件中,但该任务并未运行(仿佛更改未被注册)。

我只是想找到一种方法,让任务:
* * * * * root python3 /var/www/discourse/script/email_me.py
在通过 ./launcher rebuild app 重建后能够运行。

你真的应该遵循 @eviltrout 的建议,使用我们的 Sidekiq 定时任务插件来正确完成此操作。

但如果你非要折腾这些不受支持的 cron 更改,那么在通过 sv restart cron 添加任务后,可能需要重启该服务。

为了更清楚起见,我想知道你的最终目标是什么,而不是你为实现它而采取的步骤。如果你的目标是一分钟给你发送一封邮件,你可以在插件中通过 Sidekiq 任务来实现,这样要简单得多。

我的最终目标是运行一个数据库查询,查找特定的用户活动,并发送一封包含结果表格的电子邮件。这封邮件将作为预付款确认,因为执行了该特定活动的用户将在当天晚些时候通过另一个由 cron 运行的脚本通过 PayPal 获得付款。

我已经有了可以完成这两项任务的脚本,但我只需要找到一种方法让 discourse 容器每周运行一次这些脚本。

我不熟悉 Sidekiq。如果它能实现这个功能,我应该从哪里开始学习?

谢谢!

(另外,我尝试过 sv restart cron 以及许多其他重启 cron 的方法,但都未能成功。)

我会从插件教程系列开始,了解插件的基本结构:

如果你想参考如何在插件中添加一个任务,discourse-assign 插件中有一个用于定期发送提醒的示例:

https://github.com/discourse/discourse-assign/blob/master/jobs/scheduled/enqueue_reminders.rb

正如建议的那样,您应该编写一个合适的插件,但以下是如何实现您所需操作的方法。

您可以在 app.yml 末尾附近的 run 部分添加类似以下内容:

  - exec: cp /shared/rr/cron.d.rr /etc/cron.d/rr

您希望将您的脚本和此文件都放在某个映射到 shared 下的目录中,而不是放在 discourse 目录中。

是的,这完全奏效了。我创建了 rr 文件夹和 cron.d.rr 文件。我将 cron 任务放入 cron.d.rr 文件中,cp 命令就成功运行了。

谢谢!

现在可以去研究如何编写一个规范的插件了…