Question:
I am doing a cron tab in AWS – Elastic Beanstalk with Ruby on Rails 3, but I don’t know what is wrong.
I have this code in my .ebextensions/default.config
1 2 3 4 5 6 7 |
container_commands: 01remove_old_cron_jobs: command: "crontab -r || exit 0" 02send_test_email: command: crontab */2 * * * * rake send_email:test leader_only: true |
I receive this error:
1 2 |
Failed on instance with return code: 1 Output: Error occurred during build: Command 02send_test_email failed . |
UPDATE 1
I tried next:
crontab.txt
1 2 |
*/2 * * * * rake send_email:test > /dev/null 2>&1 |
default.config
1 2 3 4 |
02_crontab: command: "cat .ebextensions/crontab.txt | crontab" leader_only: true |
RESULT: No errors, but it does not work.
UPDATE 2
crontab.sh
1 2 3 4 5 6 7 8 9 |
crontab -l > /tmp/cronjob #CRONJOB RULES echo "*/2 * * * * /usr/bin/wget http://localhost/crontabs/send_test_email > /dev/null 2>&1" >> /tmp/cronjob #echo "*/2 * * * * rake send_email:test > /dev/null 2>&1" >> /tmp/cronjob crontab /tmp/cronjob rm /tmp/cronjob echo 'Script successful executed, crontab updated.' |
default.config
1 2 3 4 |
02_crontab: command: "/bin/bash .ebextensions/crontab.sh" leader_only: true |
RESULT: Works with url, but not with rake task.
Answer:
Updated for 2018
In order to get this to work on the latest version of Elastic Beanstalk, I added the following to my .ebextensions
:
.ebextensions/0005_cron.config
1 2 3 4 5 6 7 8 9 10 11 12 |
files: "/etc/cron.d/mycron": mode: "000644" owner: root group: root content: | 56 11 * * * root . /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1 commands: remove_old_cron: command: "rm -f /etc/cron.d/*.bak" |
How I got there:
There are four main issues to confront when trying to cron a rake task in AWS EB:
- The first hurdle is making sure all of your EB and Rails environment variables are loaded. I beat my head against the wall a while on this one, but then I discovered this AWS forum post (login may be required). Running
. /opt/elasticbeanstalk/support/envvars
loads all of your environment variables. - Then we need to make sure we
cd
into the current app directory usingcd /var/app/current
. - Next we need to know where to find the
bundle
andrake
executables. They are not installed in the normalbin
directories, but are located in a directory specific to your ruby version. To find out where your executables are located, ssh into your EB server (eb ssh
) and then type the following:
123456$ cd /var/app/current$ which bundle/opt/rubies/ruby-2.3.4/bin/bundle$ which rake/opt/rubies/ruby-2.3.4/bin/rake
You could probably guess the directory based on your ruby version, but the above commands will let you know for sure. Based on the above, your can build your rake command as:
12/opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test
NOTE: If you update your ruby version, you will likely need to update your cron config as well. This is a little brittle. I’d recommend making a note in your README on this. Trust me, six months from now, you will forget. - The fourth thing to consider is logging. I’d recommend logging to the same location as your other rails logs. We do this by tacking on
>> /var/app/current/log/cron.log 2>&1
to the end of our command string.
Putting all of this together leads to a cron
command string of:
1 2 |
. /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1 |
Finally, I referenced the latest AWS documentation to build an .ebextensions
config file for my cron
command. The result was the .ebextensions/0005_cron.config
file displayed at the top of this answer.