[英]Docker cron scheduled job not running
我正在嘗試使用基於 Alpine 映像的 docker 容器來運行計划的 cron 作業,遵循本教程,但是在我的啟動腳本中打印語句后,容器只是退出,而沒有運行我的其他腳本。
我的 docker-compose 服務配置如下:
cron:
image: alpine:3.11
command: /usr/local/startup.sh && crond -f -l 8
volumes:
- ./cron_tasks_folder/1min:/etc/periodic/1min/:ro
- ./cron_tasks_folder/15min:/etc/periodic/15min/:ro
- ./cron_tasks_folder/hourly:/etc/periodic/hourly/:ro
- ./scripts/startup.sh:/usr/local/startup.sh:ro
所以它運行一個名為startup.sh
的初始腳本,然后啟動 cron 守護進程。 startup.sh
腳本包含以下內容:
#!/bin/sh
echo "Starting startup.sh.."
echo "* * * * * run-parts /etc/periodic/1min" >> /etc/crontabs/root
crontab -l
sleep 300
我在里面放了一個 sleep 命令,這樣我就可以在容器上啟動一個交互式 shell 並確保里面的所有東西看起來都很好。 該腳本為 1 分鍾腳本創建了另一個文件夾。 我在那里添加了一個測試腳本,我可以驗證它在那里:
/etc/periodic/1min # ls -a
. .. testScript
該腳本是可執行的:
/etc/periodic/1min # ls -l testScript
-rwxr-xr-x 1 root root 31 Jul 30 01:51 testScript
而testScript
只是一個 echo 語句,以確保它首先工作:
echo "The donkey is in charge"
查看 etc/crontabs 中的root
文件,我看到以下內容(我已經多次重新運行容器,並且每次都創建一個新的 1min 文件夾,這是不必要的,但我認為不是這里的問題):
# do daily/weekly/monthly maintenance
# min hour day month weekday command
*/15 * * * * run-parts /etc/periodic/15min
0 * * * * run-parts /etc/periodic/hourly
0 2 * * * run-parts /etc/periodic/daily
0 3 * * 6 run-parts /etc/periodic/weekly
0 5 1 * * run-parts /etc/periodic/monthly
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
testScript
的 echo 語句永遠不會打印到我的終端,並且容器在啟動后不久以退出代碼 0 退出。 我想每分鍾打印一次這個聲明......我錯過了什么?
在 docker compose 文件中,你有
command: /usr/local/startup.sh && crond -f -l 8
目的是作為一個 shell 命令運行,但從問題中完全不清楚會發生什么; 這取決於您的ENTRYPOINT
。 因為它是用[]
括號定義的,所以不會提供額外的 shell。 command
值將作為參數傳遞給ENTRYPOINT
。
假設這將成為一個 shell 命令,shell 中的&&
運行左側,如果成功,則運行右側。 所以startup.sh
需要在crond
執行之前完成。 startup.sh
以
sleep 300
crond
僅在300 秒后調用。
在任何一種情況下, crond
要么根本沒有被調用,要么sleep
沒有完成。 評論顯示發現了啟動crond
的錯誤。
使用這樣的入口點是在調用主可執行文件之前配置環境或提供運行時參數的標准做法。 要做到這一點,您應該確保使用exec
來運行主可執行文件,以便它接收信號,否則這些信號將進入運行入口點腳本的 bash shell。
所以在startup.sh
的末尾:
exec crond -f -l 8
將使用crond
替換運行startup.sh
的外殼,以便crond
接收所有信號(此時外殼消失了)。 這很微妙但很重要!
通常,使應用程序的調用盡可能簡單。 舉個例子,你的執行過程被分割成入口點、命令和啟動腳本,它們之間沒有明確的接口。 如果您將crond
直接放入 Dockerfile 並將其留在那里,您就不會掛斷調用。 有時必須在運行時提供參數,但環境變量 - 具有名稱,而不僅僅是位置 - 通常是首選。 這使調用保持簡單且調試簡單。 但是,當這不起作用時,shell 腳本入口點是一個很好的解決方案 - 只需確保exec
您的最終進程即可!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.