I'm trying to schedule backups using cron jobs as explained here.
The cron jobs do run but sadly don't execute the command inside it.
This is my schedule.rb file
every 1.minute do
command "backup perform -t my_backup"
end
Which translates to this cron file:
# Begin Whenever generated tasks for: /home/roy/Backup/config/schedule.rb
* * * * * /bin/bash -l -c 'backup perform -t my_backup'
# End Whenever generated tasks for: /home/roy/Backup/config/schedule.rb
The cron jobs then run every minute (I can see that by running grep CRON /var/log/syslog). These are my last cron jobs:
Mar 20 21:48:01 roybuntu CRON[18041]: (roy) CMD (/bin/bash -l -c 'backup perform -t my_backup')
Mar 20 21:48:01 roybuntu CRON[18040]: (roy) MAIL (mailed 37 bytes of output but got status 0x004b from MTA#012)
Mar 20 21:49:01 roybuntu CRON[18063]: (roy) CMD (/bin/bash -l -c 'backup perform -t my_backup')
Mar 20 21:49:01 roybuntu CRON[18062]: (roy) MAIL (mailed 37 bytes of output but got status 0x004b from MTA#012)
I also installed postfix because earlier I got "No MTA installed" error messages in the example above. However this didn't fix it.
Anyone familiar with this problem and/or know how to fix it?
EDIT:
Also running the cron file as a root user doesn't seem to work. I used sudo crontab -e to edit the root cron file.
This is the output when running the grep CRON /var/log/syslog command after I added a root crontab:
Mar 21 19:36:01 roybuntu CRON[9387]: (root) CMD (/bin/bash -l -c 'backup perform -t my_backup')
Mar 21 19:36:01 roybuntu CRON[9388]: (roy) CMD (/bin/bash -l -c 'backup perform -t my_backup')
Mar 21 19:36:01 roybuntu CRON[9385]: (roy) MAIL (mailed 37 bytes of output but got status 0x004b from MTA#012)
Mar 21 19:36:01 roybuntu CRON[9386]: (root) MAIL (mailed 90 bytes of output but got status 0x004b from MTA#012)
Did you try running the cron task command as the same user as your application? It may not have the permission to run that command.
Related
Dockerfile
FROM almalinux:8
# [... supervisord setup ...]
RUN dnf install -y \
crontabs
RUN sed -ri '/-session(\s+)optional(\s+)pam_systemd.so/d' /etc/pam.d/system-auth && \
sed -ri '/^[^#]/ s/systemd//g' /etc/nsswitch.conf
COPY $TEMPLATE_DIR/supervisord/crond.conf /etc/supervisord.d/crond.conf
crond.conf
[program:crond]
command=/usr/sbin/crond -nsm off
stdout_logfile_maxbytes=0
stdout_logfile=/dev/stdout
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
syslog:
2022-06-13 18:39:07,939 INFO success: crond entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
crontab -e
* * * * * touch /var/www/html/test.txt
syslog:
Jun 13 18:57:59 e60d29fd100e crontab[331]: (root) BEGIN EDIT (root)
Jun 13 18:58:15 e60d29fd100e crontab[331]: (root) REPLACE (root)
Jun 13 18:58:15 e60d29fd100e crontab[331]: (root) END EDIT (root)
Jun 13 18:59:01 e60d29fd100e CROND[334]: (root) CMD (touch /var/www/html/test.txt)
I thought the file is never touched... tried also echo, running an absolute path command... nothing. But after waiting a little (longer) and running cron with debug flags on, it seems the command does get run, but with something like a 5s to 50s delay:
load_entry()...about to parse command
2022-06-13T16:17:01.352923611Z linenum=21
2022-06-13T16:17:01.352929349Z load_entry()...returning successfully
2022-06-13T16:17:01.352934854Z ...load_user() done
2022-06-13T16:17:01.352940748Z unlinking old database:
2022-06-13T16:17:01.352960040Z check_inotify_database is done
2022-06-13T16:17:01.352966537Z user [root:0:0:...] cmd="touch /var/www/html/test.txt"
2022-06-13T16:17:01.352972511Z [10] do_command(touch /var/www/html/test.txt, (root,0,0))
2022-06-13T16:17:01.352979069Z [10] main process returning to work
2022-06-13T16:17:01.352984792Z
The huge delay seems to also pile up what I presume are queued commands to run, and the pile grows forever larger:
root 335 0.0 0.0 69708 5188 ? S 19:15 0:00 /usr/sbin/CROND -nsm off -x ext,sch,proc,pars,load,misc
root 336 94.4 0.0 69708 1440 ? Rs 19:15 8:52 /usr/sbin/CROND -nsm off -x ext,sch,proc,pars,load,misc
... multiply 10x the 2 processes above after a few minutes ...
Any clues why the huge delay and weird behavior? Disabling inotify (-i) on crond does not improve things... I'm thinking maybe a time skew issue?
I need to automate the verification of active containers with docker ps, and send updates of containers with docker pull. So i created this script file:
if docker ps | grep "fairplay";then
echo "doker fairplay ok" >> /home/ubuntu/at2.log
else
echo "doker fairplay caido" >> /home/ubuntu/at2.log
errdock=1
fi
The script works without a problem when i use manually on the terminal, but when i try with cron just don't work.
Crontab:
* * * * * root sh /home/ubuntu/at2.sh
The log when i run mannualy:
Thu Mar 25 13:33:43 -03 2021
doker fairplay ok
doker widevine ok
Thu Mar 25 13:33:44 -03 2021
The log when i run with cron:
Thu Mar 25 13:34:01 -03 2021
doker fairplay caido
doker widevine caido
Thu Mar 25 13:34:01 -03 2021
I don't want to run anything inside the container, i need to run the command in the cron that is on the host, so the following questions don't help question 1, question 2.
Your crontab syntax is not correct. I've tried your exact .sh file and I got no errors.
This is the correct one:
* * * * * sh /home/ubuntu/at2.sh
I'm not sure why you've added root user or word in crontab syntax as if you run root sh /home/ubuntu/at2.sh, you'll get Command 'root' not found.
I can also recommend you add date variable so that you know the time it's up or down:
if docker ps | grep "fairplay";then
then
echo "`date +"%D %H:%M:%S"` docker fairplay ok" >> /home/ubuntu/at2.log
else
echo "`date +"%D %H:%M:%S"` docker fairplay caido" >> /home/ubuntu/at2.log
errdock=1
fi
So I am pretty new into creating containers and I have the simple Dockerfile where I would like to run a simple python script every minute:
FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron
COPY my_python /bin/my_python
COPY root /var/spool/cron/crontabs/root
RUN chmod +x /bin/my_python
CMD cron -l 2 -f
where my_python:
print("hi world!!")
and root:
* * * * * python3 /bin/my_python
then I just create the image and the container:
docker image build -t python-test
docker container run -it --name python-test python-test
I was supposed to see every minute a print with the hi world, however when running the container ( after the image build) no logs seem to appear.
What am i doing wrong?
First, I believe you want -L 2 rather than -l 2 in your cron command line; see the man page for details.
The cron daemon logs to syslog, so if something isn't work as intended, it's a good idea to arrange to receive those messages. The busybox tool provides a simple syslog daemon that can log to an in-memory buffer and a tool for reading those logs, so I modified your Dockerfile to look like this:
FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron busybox
COPY my_python /bin/my_python
COPY root /var/spool/cron/crontabs/root
RUN chmod +x /bin/my_python
CMD busybox syslogd -C; cron -L 2 -f
After starting this, I docker exec'd into the container and ran busybox logread and found:
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (CRON) INFO (pidfile fd = 3)
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (root) INSECURE MODE (mode 0600 expected) (crontabs/root)
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (CRON) INFO (Running #reboot jobs)
So there's your problem: the permissions on the root crontab are incorrect. There are two ways to fix this problem:
We could explicitly chmod the file when we copy it into place, or
We can use the crontab command to install the file, which takes care of that for us
I like option 2 because it means we don't need to know the specifics of what cron expects in terms of permissions. That gets us:
FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron busybox
COPY my_python /bin/my_python
COPY root /tmp/root.crontab
RUN crontab /tmp/root.crontab
RUN chmod +x /bin/my_python
CMD busybox syslogd -C; cron -L 2 -f
With that change, we can confirm that the cron job is now running as expected:
Jan 24 16:59:50 8aa688ad31cc syslog.info syslogd started: BusyBox v1.30.1
Jan 24 16:59:50 8aa688ad31cc cron.info cron[4]: (CRON) INFO (pidfile fd = 3)
Jan 24 16:59:50 8aa688ad31cc cron.info cron[4]: (CRON) INFO (Running #reboot jobs)
Jan 24 17:00:01 8aa688ad31cc authpriv.err CRON[7]: pam_env(cron:session): Unable to open env file: /etc/default/locale: No such file or directory
Jan 24 17:00:01 8aa688ad31cc authpriv.info CRON[7]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 24 17:00:02 8aa688ad31cc cron.info CRON[7]: (root) END (python3 /bin/my_python)
Jan 24 17:00:02 8aa688ad31cc authpriv.info CRON[7]: pam_unix(cron:session): session closed for user root
But...there's still no output from the container! If you read through that man page, you'll find this:
cron then wakes up every minute, examining all stored crontabs,
checking each command to see if it should be run in the current
minute. When executing commands, any output is mailed to the owner of
the crontab (or to the user named in the MAILTO environment
variable in the crontab, if such exists)...
In other words, cron collects the output from programs and attempts
to mail to the user who owns the cron job. If you want to see the
output from the cron job on the console, you will need to explicitly
redirect stdout, like this:
* * * * * python3 /bin/my_python > /dev/console
With this change in place, running the image results in the message...
hi world!
...printing to the console once a minute.
I'm stumped on this one. I am using capistrano and whenver gems to manage my builds to prod. Cron is being setup correctly on prod. When I look at 'crontab -e' I see...
# Begin Whenever generated tasks for: nso
10 * * * * /bin/bash -l -c 'cd /home/user/nso/releases/20140130161552 && RAILS_ENV=production bundle exec rake send_reminder_emails --silent >> /var/log/syslog 2>&1'
...this looks correct. In /var/log/syslog I see...
Feb 3 16:10:01 vweb-nso CRON[32186]: (user) CMD (/bin/bash -l -c 'cd /home/user/nso/releases/20140130161552 && RAILS_ENV=production bundle exec rake send_reminder_emails --silent >> /var/log/syslog 2>&1')
Feb 3 16:10:01 vweb-nso postfix/pickup[31636]: 8A67B805C7: uid=1001 from=<user>
Feb 3 16:10:01 vweb-nso postfix/cleanup[32191]: 8A67B805C7: message-id=<20140203211001.8A67B805C7#vweb-nso>
Feb 3 16:10:01 vweb-nso postfix/qmgr[31637]: 8A67B805C7: from=<user#abtech.edu>, size=712, nrcpt=1 (queue active)
Feb 3 16:10:01 vweb-nso postfix/local[32193]: 8A67B805C7: to=<user#abtech.edu>, orig_to=<user>, relay=local, delay=0.03, delays=0.02/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
Feb 3 16:10:01 vweb-nso postfix/qmgr[31637]: 8A67B805C7: removed
Everything looks OK there..no?
Addtionally I can manually run the command. At the command prompt if I do.
/bin/bash -l -c 'cd /home/user/nso/releases/20140130161552 && RAILS_ENV=production bundle exec rake send_reminder_emails --silent >> /var/log/syslog 2>&1'
...I get my reminder emails as I should. What am I missing?
So this ended up being my issue...
Rails cron whenever, bundle: command not found
Once I added env :PATH, ENV['PATH'] to the top of config/schedule.rb everything worked as advertised!
In my schedule:
every 10.minutes do
runner "Model.method"
end
Whenever created this in my crontabs
0,10,20,30,40,50 * * * * /bin/bash -l -c 'cd /home/projects/Monitoring && script/rails runner -e development '\''Model.method'\'''
I tried to run the command in my console and it works. Why does it not work automaticly, i am going insane!
In my syslog
Mar 11 11:38:01 UbuntuRails CRON[20050]: (ruben) CMD (/bin/bash -l -c 'cd /home/projects/Monitoring && script/rails runner -e development '\''Ping.check_pings'\''')
Mar 11 11:38:01 UbuntuRails CRON[20048]: (CRON) info (No MTA installed, discarding output)
Mar 11 11:38:01 UbuntuRails CRON[20047]: (CRON) error (grandchild #20050 failed with exit status 1)
Mar 11 11:38:01 UbuntuRails CRON[20047]: (CRON) info (No MTA installed, discarding output)
I am on Ubuntu 10.10 and had the same problem.
Turns out the -l option does not load the environment as expected, but -i does. (see this issue)
As the issue thread states, the fix is to edit your schedule.rb and add:
set :job_template, "/bin/bash -i -c ':job'"
Cheers