Crontab In Docker
Dockerfile to run crontab tasks
Crontab in Docker for Rails
This approach allows to run cron tasks of Rails application usually maintained by Whenever gem.
Dockerfile with Cron
FROM ruby:2.4.3-slim-stretch
RUN apt-get update -qq && apt-get install --no-install-recommends -y \
build-essential \
patch \
ruby-dev \
zlib1g-dev \
liblzma-dev \
libxml2 \
libxml2-dev \
libpq-dev \
default-libmysqlclient-dev \
imagemagick \
git \
wget \
gnupg2 \
curl \
nodejs-dev \
node-gyp \
libssl1.0-dev \
cron \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch"-pgdg main | tee /etc/apt/sources.list.d/pgdg.list \
&& apt-get update -qq && apt-get install --no-install-recommends --no-upgrade -y \
postgresql-client-11 \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSLO --compressed "https://nodejs.org/dist/v8.17.0/node-v8.17.0-linux-x64.tar.xz" \
&& tar -xJf "node-v8.17.0-linux-x64.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
&& rm "node-v8.17.0-linux-x64.tar.xz" \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
&& npm install -g yarn
WORKDIR /opt/app
COPY ./config/entrypoint.sh /usr/bin/entrypoint.sh
RUN chmod +x /usr/bin/entrypoint.sh && crontab -l | { cat; echo ""; } | crontab -
RUN gem install bundler -v 2.0.1
ADD Gemfile* /opt/app/
RUN bundle install
ARG RAILS_ENV
ARG ACTION_CABLE_URL
COPY . /opt/app
RUN yarn install --check-files
RUN RAILS_ENV=$RAILS_ENV bundle exec rake assets:precompile
EXPOSE 9292
The docker-compose.yml part to start container with cron
version: "3"
services:
crontab:
image: ${PROJECT_HUB}/${PROJECT_NAME}/backend:${IMAGE_TAG}
container_name: ${PROJECT_NAME}_crontab
restart: on-failure
networks:
overlay:
aliases:
- crontab
working_dir: /opt/app
env_file:
- ./.env
command: bash -c 'env > /opt/app/cronenv && bundle exec whenever --update-crontab && cron -f'
depends_on:
- redis
- db
This file is required to run cron tasks in the same enviroment. We create it on startup.
env > /opt/app/cronenv
Setup whenever to generate tasks with following additions:
* * * * * /bin/bash -l -c 'for line in `cat /opt/app/cronenv` ; do export $line ; done && cd /opt/app && RAILS_ENV=production bundle exec rake addons:process_repeat_addons >> /var/log/cron.log 2>&1'
The approach is a bit naive, but whenever does not allow to edit command before /bin/bash, otherwise we can do as follows:
* * * * * env - `cat /opt/app/cronenv` /bin/bash -l -c 'cd /opt/app && bundle install && RAILS_ENV=production bundle exec rake addons:process_repeat_addons >> /var/log/cron.log 2>&1'