rails, whenever and docker - cron tasks doesn't run - ruby-on-rails

My crontasks from schedule.rb doesn't work on docker container, but crontab -l result already contains this lines:
# Begin Whenever generated tasks for: /app/config/schedule.rb
45 19 * * * /bin/bash -l -c 'bundle exec rake stats:cleanup'
45 19 * * * /bin/bash -l -c 'bundle exec rake stats:count'
0 5 * * * /bin/bash -l -c 'bundle exec rake stats:history'
# End Whenever generated tasks for: /app/config/schedule.rb
I can run this commands manually in container and it works. It seems like cron doesn't start.
Dockerfile:
FROM ruby:2.4.0-slim
RUN apt-get update
RUN apt-get install -qq -y --no-install-recommends build-essential libpq-dev cron postgresql-client
RUN cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
ENV LANG C.UTF-8
ENV RAILS_ENV production
ENV INSTALL_PATH /app
RUN mkdir $INSTALL_PATH
RUN touch /log/cron.log
ADD Gemfile Gemfile.lock ./
WORKDIR $INSTALL_PATH
RUN bundle install --binstubs --without development test
COPY . .
RUN bundle exec whenever --update-crontab
RUN service cron start
ENTRYPOINT ["bundle", "exec", "puma"]

In a Dockerfile, the RUN command is only execute when building the image.
If you want to start cron when you start your container, you should run cron in CMD. I modified your Dockerfile by removing RUN service cron start and changing your ENTRYPOINT.
FROM ruby:2.4.0-slim
RUN apt-get update
RUN apt-get install -qq -y --no-install-recommends build-essential libpq-dev cron postgresql-client
RUN cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
ENV LANG C.UTF-8
ENV RAILS_ENV production
ENV INSTALL_PATH /app
RUN mkdir $INSTALL_PATH
RUN touch /log/cron.log
ADD Gemfile Gemfile.lock ./
WORKDIR $INSTALL_PATH
RUN bundle install --binstubs --without development test
COPY . .
RUN bundle exec whenever --update-crontab
CMD cron && bundle exec puma
It's a best practice to reduce the number of layer an image have, for example, you should always combine RUN apt-get update with apt-get install in the same RUN statement, and clean apt files after: rm -rf /var/lib/apt/lists/*
FROM ruby:2.4.0-slim
RUN apt-get update && \
apt-get install -qq -y --no-install-recommends build-essential libpq-dev cron postgresql-client \
rm -rf /var/lib/apt/lists/* && \
cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime
ENV LANG C.UTF-8
ENV RAILS_ENV production
ENV INSTALL_PATH /app
RUN mkdir $INSTALL_PATH && \
touch /log/cron.log
ADD Gemfile Gemfile.lock ./
WORKDIR $INSTALL_PATH
RUN bundle install --binstubs --without development test
COPY . .
RUN bundle exec whenever --update-crontab
CMD cron && bundle exec puma

Related

/bin/bash: 1: ./entrypoint.sh: not found

In Debian GNU/Linux 11 (bullseye) based Dockerfile, I tried to use CMD to run an entry point command:
#EDIT
WORKDIR "/tmp"
USER root
COPY ./entrypoint.sh /tmp/rails/entrypoint.sh
RUN chmod +x /tmp/rails/entrypoint.sh
EXPOSE 80
CMD ["/bin/bash","-c","/tmp/rails/entrypoint.sh"]
/tmp/rails/entrypoint.sh:
#!/bin/bash
nginx -g 'daemon off;'
cd /tmp
RAILS_ENV=proudction bundle exec rails server -p 3000
service nginx start
But I still getting error
/bin/bash: 1: ./entrypoint.sh: not found
I also tried
ENTRYPOINT /tmp/rails/entrypoint.sh
CMD ["/bin/bash","-c","/tmp/rails/entrypoint.sh"]
but it always show entrypoint.sh not found, Any idea?
EDIT
full docker file:
FROM ruby:3.0.5
RUN apt update -y
RUN apt install -y nginx
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.6.1 /lambda-adapter /opt/extensions/lambda-adapter
RUN apt-get update -y
RUN apt-get --assume-yes install autoconf bison patch build-essential rustc libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev
RUN apt-get install -y rubygems #ruby-dev
RUN gem install bundler -v '2.2.32'
RUN bundle config --local build.sassc --disable-march-tune-native
# UPDATE NODE:
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
# YARN:
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt update && apt install yarn
# Fix issue with sassc gem
RUN bundle config --local build.sassc --disable-march-tune-native
RUN apt-get install -y awscli
#END OF ORIGINAL
#RUN bundle config set without 'development test'
#RUN rm -rf /home/app/webapp/app
RUN mkdir /tmp/rails
COPY . /tmp/rails
WORKDIR "/tmp/rails"
RUN bundle install # --path=vendor
ENV RAILS_SERVE_STATIC_FILES false
ENV EXECJS_RUNTIME=Disabled
ENV WEBPACKER_PRECOMPILE=false
ENV NODE_ENV=production
RUN yarn config set ignore-engines true
#RUN bundle exec rails webpacker:compile
RUN bundle exec rails assets:precompile
ARG GIT_REVISION_ARG
ENV GIT_REVISION=$GIT_REVISION_ARG
#Rails App
RUN rm -f /etc/service/nginx/down
RUN rm -f /etc/nginx/sites-enabled/default
ADD webapp.conf /etc/nginx/sites-enabled/webapp.conf
RUN chmod +x /tmp/rails/entrypoint.sh
WORKDIR "/tmp"
ADD nginx/app/config/ /etc/nginx/
ADD nginx/app/images/ /usr/share/nginx/html/images
USER root
COPY ./entrypoint.sh /tmp/rails/entrypoint.sh
RUN chmod +x /tmp/rails/entrypoint.sh
ENTRYPOINT /tmp/rails/entrypoint.sh
EXPOSE 80
CMD ["/bin/bash","-c","/tmp/rails/entrypoint.sh"]

Yarn executable was not detected in the system

Rails with docker gives me error when asset precompiled.
i am trying to setup rails application with docker. everything is fine but asset precompiled issue raise during build image.
Yarn executable was not detected in the system.
Dcoker file
`FROM ruby:2.7.2
ENV RAILS_ROOT /var/www/quickcard
ENV BUNDLE_VERSION 2.1.4
ENV BUNDLE_PATH usr/local/bundle/gems
ENV RAILS_LOG_TO_STDOUT true
ENV RAILS_PORT 5000
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
RUN apt-get update -qq && apt-get install -y build-essential \
git \
libxml2-dev \
libpq-dev \
libxslt-dev \
nodejs \
yarn \
imagemagick \
tzdata \
less \
&& rm -rf /var/cache/apk/*
RUN gem install bundler --version "$BUNDLE_VERSION"
RUN bundle config set path $BUNDLE_PATH
RUN mkdir -p $RAILS_ROOT
WORKDIR $RAILS_ROOT
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
COPY yarn.lock yarn.lock
RUN bundle install
EXPOSE $RAILS_PORT
RUN ln -s $RAILS_ROOT/config/systemd/puma.service /etc/systemd/system/quickcard
COPY . .
ENTRYPOINT ["entrypoint.sh"]
RUN bundle exec rake assets:precompile
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
`
How to resolve this error?

Rails run with puma in dockerfile and enable https

This is an example of a Dockerfile for ruby on rails project.
I want to run it with ssl key and cert
RUN apt-get update -yqq && apt-get install -y npm && npm install -g yarn
RUN apt-get install -y ruby-full
RUN apt install libsqlite3-dev
RUN gem install rails --version=6.1
RUN mkdir /var/app
WORKDIR /var/app
COPY . .
RUN bundle install --without development test
RUN npm install --force
RUN export SECRET_KEY_BASE=...............................
EXPOSE 3000
EXPOSE 80
EXPOSE 443
EXPOSE 8443
RUN rails webpacker:install
#RUN rake assets:clean
RUN rake assets:precompile
CMD rails s -b 0.0.0.0 -e production
FROM ruby:3.0.2
RUN apt-get update -yqq && apt-get install -y npm && npm install -g yarn
RUN apt-get install -y ruby-full
RUN apt install libsqlite3-dev
RUN gem install rails --version=6.1
RUN mkdir /var/app
WORKDIR /var/app
COPY . .
RUN bundle install --without development test
RUN npm install --force
RUN export SECRET_KEY_BASE=...............................
EXPOSE 3000
EXPOSE 80
EXPOSE 443
EXPOSE 8443
RUN rails webpacker:install
#RUN rake assets:clean
RUN rake assets:precompile
CMD puma -b 'ssl://0.0.0.0:8443?key=yourkey.key&cert=yourcertificat.pem&verify_mode=none' -b 'tcp://0.0.0.0:80' -e production
In config/environment/production.rb add: config.force_ssl=true
You can you freessl to get ssl key and certificat for your domain;
https://freessl.org/
To run it on you virtual machine or instance: docker run -d -p 443:443 -p 80:80 yourimage:tag

Cron using Whenever Rails and Docker - jobs not firing

Trying to setup whenever cron jobs on my app that runs on a docker setup with redis and sidekiq in separate containers, but haven't been able to set them to fire on a time schedule, manually it works fine.
schedule.rb file
env :PATH, ENV['PATH']
set :output, "log/cron.log"
every 1.minutes do
runner "SampleJob.perform_async"
end
Test job I am trying to run:
class SampleJob
include Sidekiq::Worker
def perform(*args)
p 'Job is running'
end
end
my Dockerfile
FROM ruby:2.7.1
ENV LANG C.UTF-8
ENV NODE_VERSION 12
ENV NODE_ENV production
ENV INSTALL_PATH /home/app/app/current
RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq
RUN apt-get install -y --no-install-recommends nodejs postgresql-client yarn build-essential vim
RUN apt-get install -y cron
RUN mkdir -p $INSTALL_PATH
WORKDIR $INSTALL_PATH
COPY Gemfile Gemfile.lock ./
RUN gem install bundler
RUN bundle install
COPY . $INSTALL_PATH
RUN rm -rf tmp
RUN useradd -Ms /bin/bash api -u 1001
RUN chown -R api:api /home/app /usr/local/bundle
USER root
RUN touch /home/app/app/current/log/cron.log
RUN bundle exec whenever --update-crontab --set environment='development'
CMD cron && bundle exec puma
RUN service cron start
EXPOSE 3100
CMD rails server -p 3100 -b 0.0.0.0
running crontab -l inside my app's container gives me:
# Begin Whenever generated tasks for: /home/app/limpar-api/current/config/schedule.rb at: 2021-05-05 17:42:43 +0000
PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/b
.
. (many path variables)
.
* * * * * /bin/bash -l -c 'cd /home/app/limpar-api/current && bundle exec bin/rails runner -e development '\''SampleJob.perform_async'\'' >> log/cron.log 2>&1'
# End Whenever generated tasks for: /home/app/limpar-api/current/config/schedule.rb at: 2021-05-05 17:42:43 +0000
Any step I might be missing from the mix?

Docker Sidekiq Starting - Rails App with Puma

The following Dockerfile it's supposed to start sidekiq when the container it's started:
FROM phusion/baseimage:0.9.18
ENV RUBY_MAJOR "2.0"
ENV RUBY_VERSION "2.0.0-p643"
ENV RUBYGEMS_VERSION "2.5.2"
ENV BUNDLER_VERSION "1.11.2"
ENV NODE_VERSION "5.5.0"
ENV BOWER_VERSION "1.7.6"
ENV APT_PACKAGES " \
git imagemagick \
gcc g++ make patch binutils libc6-dev \
libjemalloc-dev libffi-dev libssl-dev libyaml-dev zlib1g-dev libgmp-dev \
libxml2-dev libxslt1-dev libpq-dev libreadline-dev libsqlite3-dev htop \
"
ENV APT_REMOVE_PACKAGES "openssh-server"
RUN apt-get update && apt-get -y dist-upgrade
RUN apt-get install -y $APT_PACKAGES
RUN apt-get remove --purge -y $APT_REMOVE_PACKAGES
RUN apt-get autoremove --purge -y
WORKDIR /tmp
RUN curl -o ruby.tgz \
"https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR}/ruby-${RUBY_VERSION}.tar.gz" && \
tar -xzf ruby.tgz && \
cd ruby-${RUBY_VERSION} && \
./configure --enable-shared --with-jemalloc --disable-install-doc && \
make -j4 && \
make install && \
rm /usr/local/lib/libruby-static.a
ENV GEM_SPEC_CACHE "/tmp/gemspec"
RUN echo 'gem: --no-document' > $HOME/.gemrc
RUN gem update --system ${RUBYGEMS_VERSION}
RUN gem install -v ${BUNDLER_VERSION} bundler
RUN curl https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz \
|tar -xz -C /usr --strip-components=1
RUN npm install bower#${BOWER_VERSION} -g
RUN rm /etc/my_init.d/00_regen_ssh_host_keys.sh
RUN rm -r /etc/service/sshd
RUN useradd -m app
RUN mkdir /home/app/webapp && chown app:app -R /home/app
RUN rm -rf /tmp/* /var/tmp/* /var/lib/apt /var/lib/dpkg /usr/share/man /usr/share/doc
WORKDIR /home/app/webapp
# Copy the Gemfile as well as the Gemfile.lock and install
# the RubyGems. This is a separate step so the dependencies
# will be cached unless changes to one of those two files
# are made.
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5 --without development test
# Copy the main application.
COPY . ./
COPY .cron/daily_run_app /etc/cron.daily/
RUN chmod a+x /etc/cron.daily/daily_run_app
# Precompile Rails assets
RUN bundle exec rake assets:precompile
EXPOSE 3000
COPY .conf_files/sidekiq.sh /etc/service/sidekiq/run
COPY .conf_files/appserver.sh /etc/service/appserver/run
# Start puma
RUN chmod a+x /etc/service/appserver/run
ENTRYPOINT /etc/service/appserver/run
#ENTRYPOINT bundle exec puma -C config/puma.rb
# Start sidekiq
#ENTRYPOINT bundle exec sidekiq -L log/sidekiq.log
#RUN chmod a+x /etc/service/sidekiq/run
#ENTRYPOINT /etc/service/sidekiq/run
The script /etc/service/appserver/run:
#!/bin/bash
SIDEKIQ_THREADS=${SIDEKIQ_THREADS:-16}
cd /home/app/webapp
exec chpst -u app bundle exec puma -C config/puma.rb \
2>&1 |logger -t appserver
SIDEKIQ_CONFIG="/home/app/webapp/config/sidekiq.yml"
exec chpst -u root bundle exec sidekiq -t 5 -c $SIDEKIQ_THREADS -C $SIDEKIQ_CONFIG \
2>&1 |logger -t sidekiq
You can enquequed jobs because you can see that in the sidekiq dasboard, but they are not going to be processed because sidekiq it's not started, but it should be started with the Dockerfile and Script that are shown above. So when you type manually:
bundle exec sidekiq
Right here sidekiq it's started and the jobs now could be processed. what could be happening?

Resources