Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

docker exec is not working in cron

I have pretty simple command which is working fine standalone as a command or bash script but not when I put it in crontab

40 05 * * * bash /root/scripts/direct.sh >> /root/cron.log

which has following line

PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
SHELL=/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root/
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/

I tried to change the url of script to /usr/bin/scirpts/ no luck

I even tried to run script directly in cron

26 08 * * * docker exec -it mongodb mongodump -d meteor -o /dump/ >> /root/cron.log

with no luck, any help appreciated.

EDIT

I don't see any errors in /root/cron.log file either

like image 465
user555 Avatar asked May 07 '16 13:05

user555


4 Answers

Your docker exec command says it needs "pseudo terminal and runs in interactive mode" (-it flags) while cron doesn't attach to any TTYs.

Try changing your docker exec command to this and see if that works?

docker exec mongodb mongodump -d meteor -o /dump/
like image 156
VDR Avatar answered Oct 14 '22 22:10

VDR


for what it's worth I had this exact same problem. Fixing your PATH, changing permissions, and making sure you are running as the appropriate docker user are all good things, but that's not enough. It's going to continue failing because you are using "docker exec -it", which tells docker to use an interactive shell. Change it to "docker exec -t" and it'll work fine. There will be no log output anywhere telling you this, however. Enjoy!

like image 45
Jason Hughes Avatar answered Oct 14 '22 23:10

Jason Hughes


cron debugging

1. /var/log or sendmail

As crond work as a daemon, without ability of failing, execution is more important than logging. Then by default, if something goes wrong, cron will send a mail to $USER@localhost reporting script output and errors.

Have a look at /var/mail or /var/spool/mail for some mails, maybe

and at /etc/aliases to see where root's mail are sents.

2. crond and $PATH

When you run a command by cron, have care that $PATH is user's default path and not root default path (ie no */sbin and other reserved path to super user tools).

For this, the simplier way is to print your default path in the environment where everything run fine:

echo $PATH

or patch your script from command line:

sed -e "2aPATH='$PATH'" -i /root/scripts/direct.sh

This will add current $PATH initializer at line 2 in your script.

Or this, will whipe from your script all other PATH=:

sed -e "s/PATH=[^ ]*\( \|$\)/\1/;2aPATH='$PATH'" -i /root/scripts/direct.sh

3. Force logging

Add at top of your script:

exec 1>/tmp/cronlog-$$.log
exec 2>/tmp/cronlog-$$.err

Try this:

sed -e '1a\\nexec 1>/tmp/cronlog-$$.log\nexec 2>/tmp/cronlog-$$.err' -i ~/scripts/direct.sh

Finalized script could look like:

#!/bin/bash

# uncomment two following lines to force log to /tmp
# exec 1>/tmp/cronlog-$$.log
# exec 2>/tmp/cronlog-$$.err

PATH='....' # copied from terminal console!

docker exec -it mongodb mongodump -d meteor -o /dump/

Executable flag

If you run your script by

40 05 * * * bash /root/scripts/direct.sh

no executable flag are required, but you must add them:

chmod +x ~/scripts/direct.sh

if you want to run:

40 05 * * * /root/scripts/direct.sh
like image 8
F. Hauri Avatar answered Oct 14 '22 22:10

F. Hauri


1) Make sure this task is in the root user's crontab - it's probably the case but you didn't write it explicitly

2) cron may be unable to find bash. I would remove it and call directly your script after making it executable:

chmod 755 /root/scripts/direct.sh

and then set your crontab entry as 40 05 * * * /root/scripts/direct.sh 2>&1 >> /root/cron.log

If it's still not working, then you should have some useful output in /root/cron.log

like image 6
mbarthelemy Avatar answered Oct 14 '22 23:10

mbarthelemy