I'm trying to run a repetitive task using the Whenever gem for my rails app. It is running in a Docker container created using Docker Compose and hosted on an Ubuntu server.
I can successfully create and update the crontab file using the Whenever gem but it doesn't seem to be executing the task.
The task I want to execute repetitively in the background while the app is running is:
rake searchkick:reindex CLASS=Property
I usually execute this command successfully from the terminal after creating a web run container using 'docker-compose run web bash'. This reindexes my ElasticSearch server using the searchkick gem.
The relevant versions are below:
- ruby 2.7.2p137
- rails (6.0.3.6)
- elasticsearch (6.8.3)
- elasticsearch-api (= 6.8.3)
- elasticsearch-transport (= 6.8.3)
- searchkick (4.4.4)
- activemodel (>= 5)
- elasticsearch (>= 6)
- hashie
- whenever (1.0.0)
- chronic (>= 0.6.3)
Cron is installed using the Dockerfile:
RUN apt-get update -qq && \
apt-get install -y curl \
build-essential \
libpq-dev \
cron \
vim \
nano \
postgresql \
postgresql-contrib \
postgresql-client
The Dockerfile runs a script when the container is created:
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
The script (entrypoint.sh) creates a crontab file.
#!/bin/bash
set -e
# For development check if the gems as installed, if not, then uninstall them.
if ! [ bundle check ]; then
bundle install
fi
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid
# Yarn - Check Files.
yarn install --check-files
# Create empty crontab file.
crontab -l | { cat; echo ""; } | crontab -
# Update crontab file using whenever command.
bundle exec whenever --set 'environment=production' --update-crontab
# Run the command - runs any arguments passed into this entrypoint file.
exec "$@"
The 'bundle exec whenever --set 'environment=production' --update-crontab' command above updates the crontab file as per the schedule.rb file below:
set :output, "log/cron_log.log"
env :PATH, ENV['PATH']
# Reindex Property records every 3 mins.
every 3.minutes do
rake "searchkick:reindex CLASS=Property"
end
I've also tried using this:
every 3.minutes do
command "cd /myapp && rake searchkick:reindex CLASS=Property"
end
When I execute 'docker-compose run web bash' to use the rails terminal, I see this response at the end:
no crontab for root
[write] crontab file updated
To check that it was created correctly, I view the crontab file in the rails app with 'crontab -l' and it shows:
# Begin Whenever generated tasks for: /myapp/config/schedule.rb at: 2021-04-24 13:07:12 +0000
PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /bin/bash -l -c 'cd /myapp && RAILS_ENV=production bundle exec rake searchkick:reindex CLASS=Property --silent >> log/cron_log.log 2>&1'
# End Whenever generated tasks for: /myapp/config/schedule.rb at: 2021-04-24 13:07:12 +0000
Update: After using cron service status
and cron service start
, the logs in myApp/log/cron_log.log show the following:
bundler: failed to load command: rake (/usr/local/bin/rake)
Bundler::GemNotFound: Could not find rake-13.0.3 in any of the sources
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:86:in `block in materialize'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `map!'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `materialize'
/usr/local/lib/ruby/2.7.0/bundler/definition.rb:170:in `specs'
/usr/local/lib/ruby/2.7.0/bundler/definition.rb:237:in `specs_for'
/usr/local/lib/ruby/2.7.0/bundler/definition.rb:226:in `requested_specs'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:101:in `block in definition_method'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:20:in `setup'
/usr/local/lib/ruby/2.7.0/bundler.rb:149:in `setup'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `block in <top (required)>'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:136:in `with_level'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:88:in `silence'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `<top (required)>'
bundler: failed to load command: rake (/usr/local/bin/rake)
Bundler::GemNotFound: Could not find rake-13.0.3 in any of the sources
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:86:in `block in materialize'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `map!'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `materialize'
/usr/local/lib/ruby/2.7.0/bundler/definition.rb:170:in `specs'
/usr/local/lib/ruby/2.7.0/bundler/definition.rb:237:in `specs_for'
/usr/local/lib/ruby/2.7.0/bundler/definition.rb:226:in `requested_specs'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:101:in `block in definition_method'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:20:in `setup'
/usr/local/lib/ruby/2.7.0/bundler.rb:149:in `setup'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `block in <top (required)>'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:136:in `with_level'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:88:in `silence'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `<top (required)>'
So it seems to have set up the crontab file and the cronjob is trying to run but it is not finding rake-13.0.3. I'm going to check if this is an issue with the bundler gem version versus what is in the gemfile.
Appreciate any help.