[Ruby] No such file or directory-crontab when handling whenever with Docker

2 minute read

A convenient gem “whenever” that allows you to easily write scheduled processing

I tried to process using whenever when creating an application with docker, but since it got stuck, I will describe it as a memorandum.

environment

Ruby 2.5.1 Rails 5.2.4.3

Thing you want to do

This time, prepare a model called post and create a post every minute using whenever. Start as if the environment construction of docker is completed.

create model and controller

on docker

[email protected]:/myapp# bundle exec rails g model post name:string
[email protected]:/myapp# bundle exec db:migrate
[email protected]:/myapp# bundle exec rails g controller posts

whenever setting

First install gem

Gemfile


gem'whenever', require: false

After rebuilding and installing the gem, execute the command to create the file

[email protected]:/myapp# bundle exec wheneverize.
[add] writing `./config/schedule.rb'
[done] whenever!

I will process the created schedule.rb.

schedule.rb


require File.expand_path(File.dirname(__FILE__) + "/environment")
set :environment, :development
set :output,'log/cron.log'
ENV.each {|k, v| env(k, v)}

every 1.minutes do
  runner "Post.create"
end

After this, reflect the settings in cron

[email protected]:/myapp# bundle exec whenever --update-crontab
bundler: failed to load command: whenever (/usr/local/bundle/bin/whenever)
Errno::ENOENT: No such file or directory-crontab
  /usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:77:in `popen'
  /usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:77:in `write_crontab'
  /usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:38:in `run'
  /usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:6:in `execute'
  /usr/local/bundle/gems/whenever-1.0.0/bin/whenever:44:in `<top (required)>'
  /usr/local/bundle/bin/whenever:23:in `load'
  /usr/local/bundle/bin/whenever:23:in `<top (required)>'

I got an error. I’m a cron newbie and am stumbled upon here.

Install cron

Apparently, cron must be installed in the docker environment, so the process required for installation is described in the dockerfile. This time I added one line like this.

FROM ruby:2.5.1
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN apt-get install -y cron # Add this line
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY ./myapp
[email protected]:/myapp# bundle exec whenever --update-crontab
[write] crontab file updated

It was updated successfully and reflected in cron. I think that the automatic processing has started with this, I will wait for a while…

… Apparently not working. If whenever is working, clog/cron.log should be created.

Start cron

Check the status because cron is not running.

[email protected]:/myapp# service cron status
[FAIL] cron is not running ... failed!

After all it wasn’t working. Let’s start.

[email protected]:/myapp# service cron start
[ok] Starting periodic command scheduler: cron.

1 minute later…

cron.log


Running via Spring preloader in process 122

Finally cron.log was generated and the log was written. Check with rails console.

[email protected]:/myapp# bundle exec rails c
Running via Spring preloader in process 135
Loading development environment (Rails 5.2.4.3)
irb(main):001:0> Post.all.count
   (4.5ms) SELECT COUNT(*) FROM "posts"
=> 1

You can see that the data has been generated!

Task

However, it is troublesome to start cron manually every time, so if possible, I would like to describe it in a dockerfile so that it will be started automatically. I think I will add that method in the future.