Search code examples
rubydockerdockerfilerakewhenever

Configure Dockerfile to Run Cron Tasks using Whenver and Rake


I want to create a container using Docker which is will be responsible for starting recurrent rake tasks based on the Whenever gem's configuration. I have a plain ruby project (without rails/sinatra) with the following structure:

Gemfile:

source 'https://rubygems.org'
gem 'rake', '~> 12.3', '>= 12.3.1'
gem 'whenever', '~> 0.9.7', require: false
group :development, :test do
  gem 'byebug', '~> 10.0', '>= 10.0.2'
end
group :test do
  gem 'rspec', '~> 3.5'
end

config/schedule.rb: (whenever's configuration)

ENV.each { |k, v| env(k, v) }
every 1.minutes do
  rake 'hello:start'
end

lib/tasks/hello.rb: (rake configuration)

namespace :hello do
  desc 'This is a sample'
    task :start do
    puts 'start something!'
  end
end

Dockerfile:

FROM ruby:2.5.3-alpine3.8

RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
    apk update && apk upgrade && \
    apk add build-base bash dcron && \
    apk upgrade --available && \
    rm -rf /var/cache/apk/* && \
    mkdir /usr/app

WORKDIR /usr/app

COPY Gemfile* /usr/app/

RUN bundle install

COPY . /usr/app

RUN bundle exec whenever --update-crontab

CMD ['sh', '-c', 'crond && gulp']

I've used the following resources to get at the this point

If I call my rake task using command line, I get the result I want.

$ rake 'hello:start'
start something!

However, I can't figure out how to make it work using Docker. The container is build but no log is written, no output is shown, nothing happens. Can someone help me showing what I'm doing wrong?

building commands

docker build -t gsc:0.0.1 .
docker container run -a stdin -a stdout -i --net host -t gsc:0.0.1 /bin/bash

Thanks all. Cheers


Solution

  • This is the solution to the problem I listed above. I had some issues at the Dockerfile and schedule.rb. This is what I had to change to make it work correctly.

    Dockerfile

    • wrong echo call
    • wrong bundle command
    • change ENTRYPOINT instead of CMD
    FROM ruby:2.5.3-alpine3.8
    
    RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/main && \
        apk update && apk upgrade && \
        apk add build-base bash dcron && \
        apk upgrade --available && \
        rm -rf /var/cache/apk/* && \
        mkdir /usr/app
    
    WORKDIR /usr/app
    
    COPY Gemfile* /usr/app/
    
    RUN bundle install
    
    COPY . /usr/app
    
    RUN bundle exec whenever -c && bundle exec whenever --update-crontab && touch ./log/cron.log
    
    ENTRYPOINT crond && tail -f ./log/cron.log
    

    config/schedule.rb

    • no need to ENV.each
    every 1.minutes do
      rake 'hello:start'
    end
    

    UPDATE

    I've created a GitHub repository and a Docker Hub repository to share with the community this progress.