Cron is relatively simple if you have access to your Dockerfile (I suppose you do).
First of all, install the cron package by adding the corresponding line(s) to your Dockerfile:
RUN apt-get update
RUN apt-get install -y cron
Once the cron is installed, let’s configure it. Here is a sample crontab
file that instructs to run a script every minute:
SHELL=/bin/sh
* * * * * /app/every_1min.sh >> /app/var/log/cron.log 2>&1
Let’s save that file as etc/crontab
in your project. Then, we should instruct Docker to copy it to VM by adding the following line to the Dockerfile:
COPY etc/crontab /app/etc/crontab
And here is how our every_1min.sh
file looks like:
#!/bin/sh
echo "Hello from cron"
We should copy it to the docker image too:
COPY every_1min.sh /app/every_1min.sh
Now comes the most interesting part. The entry point of the image is represented by CMD
directive in Dockerfile. Let’s ensure that we enter our script first so that we can prepare and run our things more naturally.
Here is run.sh
script itself:
#!/bin/sh
# Terminate the script on first error.
set -e
# Create directory for log.
mkdir -p /app/var/log
# Load cron configuration.
crontab /app/etc/crontab
# Start cron as a daemon.
cron
# Run your main app.
...
Of course, before we’ll be able to start the script we should copy it first:
COPY run.sh /app/run.sh
And here is CMD
directive that starts the script (usually located at the very end of the Dockerfile):
CMD /app/run.sh
You can ensure that cron is working by connecting to VM with
flyctl ssh console
and then looking at /app/var/log/cron.log
file. It should have the following lines appended every minute:
Hello from cron
Hello from cron
...
Now you can put whatever command you want to every_1min.sh
script and fine-tune the schedule in crontab
.
It may be tricky to get it going at first, but once you make it run it becomes endlessly scalable and ready for reuse in other projects.