Can´t execute a cron with whenever in Ruby on Rails

71 views Asked by At

So I'm new to Ruby on Rails and I´m doing a simples crontab. I'm using 'whenever' with 'rbenv'.

    env :PATH, ENV['PATH']
    set :output, './log/cron.log'
    set :environment, 'development'
    every 1.minute do
      runner "puts 'Ola mundo!'"
    end

crontab -l

# Begin Whenever generated tasks for: /Users/pedrodiogo/Desktop/branch_csv_diario/config/schedule.rb at: 2024-02-05 14:23:27 +0000
PATH=/usr/local/var/rbenv/versions/3.1.2/bin:/opt/homebrew/Cellar/rbenv/1.2.0/libexec:/opt/homebrew/opt/postgresql@13/bin:/opt/homebrew/opt/postgresql@13/bin:/usr/local/var/rbenv/shims:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/Frameworks/Python.framework/Versions/3.12/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/homebrew/opt/postgresql@13/bin:/usr/local/var/rbenv/shims:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/Frameworks/Python.framework/Versions/3.12/bin

* * * * * /bin/bash -l -c 'cd /Users/pedrodiogo/Desktop/branch_csv_diario && bundle exec bin/rails runner -e development '\''puts '\''\'\'''\''Ola mundo!'\''\'\'''\'''\'' >> ./log/cron.log 2>&1'

# End Whenever generated tasks for: /Users/pedrodiogo/Desktop/branch_csv_diario/config/schedule.rb at: 2024-02-05 14:23:27 +0000

and I don't know why I'm receiving this error:

cut: /Users/pedrodiogo/Desktop/branch_csv_diario/.ruby-version: Operation not permitted
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/bundler_version_finder.rb:80:in `pwd': Operation not permitted - getcwd (Errno::EPERM)
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/bundler_version_finder.rb:80:in `lockfile_contents'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/bundler_version_finder.rb:68:in `lockfile_version'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/bundler_version_finder.rb:22:in `bundler_version_with_reason'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/bundler_version_finder.rb:7:in `bundler_version'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/bundler_version_finder.rb:45:in `filter!'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/dependency.rb:284:in `matching_specs'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:272:in `find_spec_for_exe'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
    from /usr/bin/bundle:23:in `<main>'

If I run this command in the project terminal

bin/rails runner -e development "puts 'Ola mundo!'" >>./log/cron.log

The command run without a problem!

I'm using

ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin23]

My final idea is to create a job to get data from the web and put it on Postgres database (this is already done). And I need this to execute everyday. So I thought about combine gem 'whenever' with gem 'delayed_job_active_record'. am I in the right way?

2

There are 2 answers

1
Fábio Batista On

Check (and add to your question) your crontab entry. Running Ruby scripts via CRON is not a trivial task, specially if you use Bundler, non-standard gems and/or RVM. You'll have to make sure the environment variables are correct, and most likely will have to switch the current working directory to a writable one.

To check your current crontab entry, use crontab -l. To edit it, use crontab -e.

A good practice when running more complex scripts on CRON is to write a wrapper script in sh or bash. There's a lot of references about it here on SO.

If you are using RVM, their website has a dedicated page with instructions on how to make it work with CRON, check their website for more info: https://rvm.io/deployment/cron

0
Pedro Diogo On

I could solve this problem but I think this is not the best way. So this code

set :output, './log/cron.log'
set :environment, 'development'

every 1.minute do
  runner 'puts "Ola mundo!"'
end

Was creating this crontab

* * * * * /bin/bash -l -c 'cd /Users/pedrodiogo/Desktop/branch_csv_diario && bundle exec bin/rails runner -e development '\''puts "Ola mundo!"'\'' >> ./log/cron.log 2>&1'

So this cron wasn't getting the rbenv version correct so I add this line

set :path, '/Users/pedrodiogo/Desktop/branch_csv_diario'
job_type :rbenv_rails_runner, 'cd :path && /usr/local/var/rbenv/versions/3.1.2/bin/bundle exec bin/rails runner -e :environment ":task" :output'

every 1.minute do
  rbenv_rails_runner 'puts "Ola mundo!"'
end

and this way I m telling the cron to get the rbenv version.

this creates this crontab

* * * * * /bin/bash -l -c 'cd /Users/pedrodiogo/Desktop/branch_csv_diario && /usr/local/var/rbenv/versions/3.1.2/bin/bundle exec bin/rails runner -e development "puts \"Ola mundo!\"" >> ./log/cron.log 2>&1'

I think this is not the right way! Hope getting some feedback from seniors developers!