Hej! Jest to pytanie trochę z dziedziny unix/konfiguracji serwera ale wydaje się być niejako powiązane z rubym więc spróbuje szczęścia tutaj. Zaznaczam, że mam na codzień do czynienia z unixami całkiem sporo więc nie jestem totalnie zielony. Są jednak sprawy, których zupełnie nie rozumiem i nie jestem w stanie ich ogarnać hehe.
Mam na swoim VPSie (Ubuntu 14.04 LTS / ruby 2.2.1 (bez rvm)) aplikację z rake taskiem, który musi być odpalany co jakiś czas przez crona. Wpis w crontabie wygląda następująco:
Niestety efekt jest taki, że cron uruchamia to polecenie w odpowiednim czasie, jednak plik cron.log zawsze jest pusty, cron nie wypluwa nigdzie żadnych błędów (nie dostaje ich również na maila) a rake task nie jest uruchamiany - albo raczej jego zawartość nie jest uruchamiana. Jedyny znak, że cokolwiek się wydarzyło to wpis w syslogu:
Co ciekawe - jestem w stanie uruchomić dokładnie to polecenie w /bin/sh i wszystko działa jak należy.
Główny problem polega na tym, że nie jestem w stanie tego w żaden sposób zdebugować dlatego w pierwszej kolejności zapytam co mogę zrobić, żeby jakkolwiek to zdebugować? Jeśli jednak ktoś widzi tutaj ewidentny błąd z mojej strony, to będę dozgonnie wdzięczny za pomoc i wyjaśnienie.
Nie przepadam za takimi skryptami z crona, ciężko się to ustawia, wersjonuje, utrzymuje i debuguje.
Ale może coś pomogę:
Nie wiem, czy ustawiasz w tym crontabie jakieś zmienne środowiskowe (w sensie, przed deklaracjami co kiedy uruchomić, np PATH, RUBY_ROOT etc), jak nie, to bundle exec nie zadziała.
Przekierowanie outputu też wygląda dziwnie (&>> w os x to nie śmiga), do przekierowanie stderr do stdout możesz użyć 2>&1 .
rake RAILS_ENV=production … prawdopodobnie, działa, ale lepiej sobie wyrobić nawyk ustawiania zmiennych “skrajnie po lewej”, tj
Twoje polecenie może się już wywalać na poziomie “cd /home/deploy/my_app/current” i nie będziesz o tym wiedział bo przekierowanie błędów robisz tylko dla tej drugiej części. Dodatkowo nie przekierowujesz stderr. Zupełnie niepotrzebny jest znak ‘&’. Po to odpalasz w cronie żeby nie udawać pseudo backgrandowego odpalania, prawda? Zacznij więc od poprawienia tych rzeczy:
Spodziewam się tutaj klasycznego problemu - crontab nie widzi rubiego/bundlera. Zwykle jest to spowodowane tym, że logując się przez ssh masz inne środowisko niż to tworzone przez crona.
Można to sprawdzić przez najprostszy task w cronie:
* * * * * echo $PATH >/tmp/env.log
Na świeżo postawionej maszynce ubuntu (przez Vagrant) dostaję:
Jak temu zaradzić? To zależy :-). Jeśli zmienne te są ustawiane w ~/.bashrc lub ~/.bash_profile (np. jak używamy rbenv) to można przekazać opcje -i i -l do basha żeby odpalić sesję “interactive” i “login” (co spowoduje wczytanie tych plików):
ps. Odpalanie polecenia bundle exec /usr/local/bin/rake nie ma za bardzo sensu. Skoro odpalasz przez bundlera tzn. że rake musi być w zależnościach, zatem wystarczy bundle exec rake
Hi. The short answer is to include ruby executables to your PATH variable. But also I recommend as it was already proposed to use gem whenever. Then you don’t need manually edit crontab just use familiar ruby syntax for sheduling cron jobs. Also this gem has nice integration with capistrano and as I see current in your path string I guess you are using capistrano for deployment.
Here is the example of my own configuration. config/schedule.rb
every 15.minutes do
rake 'transaction:clean_expired'
rake 'transaction:mark_unpaid'
end
lib/tasks/transaction.rake
namespace :transaction do
desc 'Remove expired transactions'
task clean_expired: :environment do
Transaction.expired.destroy_all
end
# some other code
end
Don’t forget to require ‘whenever/capistrano’ in your Capfile(if you are using capistrano)
After each deploy your ruby shedule will be turned in crontab entry. Something like
It’s very similar to the cronjob you wrote manullay but the risk to make a mistake with updating frequency or other condition is minimal. But still there is a problem that ruby executables are not accesible by cron job. to solve this I’ve added this line to ~/.bashrc
export PATH="$HOME/.rbenv/bin:$PATH"
Keep in mind I’m using rbenv for ruby version management. If you are using rvm or just manually installed ruby you should provide corresposnding path.
p.s Nie wiem czy język angielski jest zezwolony w tym forumie. Ale mój polski jeszcze jest bardzo slaby.