This content originally appeared on DEV Community and was authored by Kevin Luo
Introduction
I just started learning and practicing Kamal. While I found it's a joy to finally be able to deploy Docker images on my own machine, there are some challenges. One of the biggest challenges is that it's unreasonably difficult to run cron jobs 🥲 On top of that, I like to use the whenever gem to manage cron jobs, which makes it even harder.
I came across a helpful blog post by Alan Morales, which already solves this issue. However, after some research and experiments, I came up with a simpler version, and I'd like to share it here.
Some terms
We know cron
is the program that runs routine jobs—like running a script every 5 minutes. cronjobs
just means the jobs that will be run by cron
. crontab
is the command used to edit the cronjobs
. (I guess crontab
stands for cron table, but I don't have proof for that 😄)
Official Tutorial
The official tutorial suggests running "cron" jobs as a separate server in Kamal. If you check out the tutorial at https://kamal-deploy.org/docs/configuration/cron/, it gives a very concise (but actually clever) example:
bash -c "(env && cat config/crontab) | crontab - && cron -f"
If you follow this exactly, I bet 99% of the time it won’t work for you. Let’s have a close look at this command:
-
bash -c
: starts a new Bash session to execute the commands. -
(env && cat config/crontab)
:env
prints all current environment variables.cat config/crontab
outputs the contents of the crontab file, which should have cronjob entries like0 5 * * * /path/to/script.sh
. -
| crontab -
: pipes the combined output intocrontab -
, which updates the cron jobs. -
cron -f
: runscron
in the foreground so the Docker container stays alive.
From this, we know we need:
- The
cron
program installed in the Docker image. - An existing cronjobs file to set up with
crontab
. - Environment variables (
env
) at the top of the crontab file becausecron
doesn’t source profile files like.bashrc
or.zshrc
. Rails commands need variables likePATH
,BUNDLE_PATH
,RAILS_ENV
, etc. - One more thing:
cron
is designed to run as the root user. Running it as a non-root user often causes "Permission Denied" errors.
Proposed Method
1. Install cron
in the Dockerfile
Just like the blog post suggests, you need to have cron
installed:
# Install cron
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y cron && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives && \
rm -rf /etc/cron.*/*
2. Modify the cmd
In your deploy.yml
, set up the cron server like this:
servers:
cron:
hosts:
- www.xxx.yyy.zzz # your server IP
cmd: bash -c "bundle exec whenever --update-crontab && (env && crontab -l) | crontab - && cron -f"
options:
user: root
Explanation:
-
bundle exec whenever --update-crontab
: updates the crontab usingwhenever
. -
(env && crontab -l)
: prints environment variables and current crontab. -
| crontab -
: sets the new crontab. -
cron -f
: runscron
in the foreground. -
options.user: root
: indicates to useroot
to run the server
The key part is this single line:
bash -c "bundle exec whenever --update-crontab && (env && crontab -l) | crontab - && cron -f"
3. (Optional) Print cron output to Docker’s stdout
Debugging cron in Docker is hard because you can't see the logs. Here's a simple trick: redirect the cron output to Docker’s stdout. Add this line to the top of your config/schedule.rb
:
set :output, { standard: '/proc/1/fd/1', error: '/proc/1/fd/2' }
The mysterious /proc/1/fd/1
and /proc/1/fd/2
point to the Docker container logs. You can then check the cron output with:
kamal app logs -r cron -f
Conclusion
In every stage of my career, I’ve found that running cron jobs on production servers is never easy. Running them in Docker makes it even trickier 😆. I hope this changes in the future, but until then, we just have to figure out our own ways.
References
- https://world.hey.com/alan.m/cronjobs-using-kamal-and-whenever-gem-ddd901f9
- https://github.com/basecamp/kamal/issues/47#issuecomment-1865975293
This content originally appeared on DEV Community and was authored by Kevin Luo

Kevin Luo | Sciencx (2025-07-09T02:25:59+00:00) Running Cron Jobs by Kamal with the Whenever Gem (The Simple Way). Retrieved from https://www.scien.cx/2025/07/09/running-cron-jobs-by-kamal-with-the-whenever-gem-the-simple-way/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.