Migrating From Dokku to Kamal: Scheduling Cron Jobs
This is the third post of the series "Migrating From Dokku to Kamal" and today I am gonna show you how I've set cron with Kamal, click here to read the second post of the series in case you've missed it.
I needed a way run periodic tasks on Kamal to replace Dokku's scheduled cron tasks.
Cron seemed the way to go according to this pull request on the Kamal repo, but making it work turned out to be not so simple as that.
The idea is to have a new container on the worker
server responsible for scheduling jobs defined on a crontab file.
Defining cron jobs
First thing is to create this crontab file defining the tasks to be scheduled by cron, I've put this file on config/app.crontab
:
Note that I am passing the command I want to run (make whatever
in this case) to a bin/cron-executor.sh
:
this shell script is responsible for doing a few things before running the desired command:
- adds
/usr/local/bin
to$PATH
, so ruby and bundle can be loaded - enters the directory of the application (
/rails
) - prints the command that is about to be executed
- executes the command
In case you are wondering, >/proc/1/fd/1 2>/proc/1/fd/2
is required to redirect the output of the command to the container's stdout/stderr. If you don't add this, you won't be able to see the logs of the cron jobs when running docker logs
for example.
Setting up the Dockerfile
The next step is to make sure the application's Dockerfile
installs cron and applies the jobs from the crontab file we just defined:
USER root
. Please let me know in case you managed to get that working.Passing environment variables to cron
Cron reads environment variables from /etc/environment
, so we need to set them there by adding one line to bin/docker-entrypoint
:
Defining a new server
The last step is to define a new server on Kamal's deploy.yml
with the same ip as the worker
:
Note that bash -c "cron -f -L 2"
is set as the command to run on the container, it'll make cron to run on the foreground and set the logging verbosity.
That's all folks, I hope you have enjoyed the series.
Ps: I'd like to thank you Jason for writing this post on running cron on Docker, it was really useful to me!