Laravel Scheduler in Docker container

Recently we have moved our Laravel application's infrastructure to kubernetes. Everything went well except for scheduling jobs.

Laravel scheduler should be called every minute by running artisan scheduler:run command. Then by simply writing a php code you can schedule more jobs from the application code. That is a cool thing since you don't have to update the image in case you need a new job to be run.

What to use?

The decision was to use the second option with a single instance.

The problem

Then there was a lot of problems with setting cron to read environment variables. Compared to other images that were responsible for serving requests, for example, it required some ugly hacks. There are some suggestions online but everything looks messy: like passing a list of environments and inject them in the beginning of the crontab file, echoing environment variables and then read them by the script... Some of these things didn't even work. Also one of the constraints was that we didn't want to run it as a root user.

Alternatives

So the next step was to find some alternatives:

Jobber is an alternative to cron written in go. It was hard for me to integrate it into the existing docker image. I had problems with installation on Ubuntu.

Another one is yacron but after so many difficulties with the first one (and it has fewer stars on Github if that means anything) I gave up.

Some articles discouraged me even more to use those alternatives.

Custom script (current solution)

After lots of problems with getting cron to work and it's alternatives, I decided to write a custom bash script that will just sleep for one minute and run the command.

while true
do
    php /app/artisan schedule:run &
    sleep 60
done

My concern here was the cumulative error that could happen when the scheduler works for long period of time. Following script is more complicated but it contains error correction logic.

Other working solutions

In the end, I was satisfied with the solution. It is even possible to get all the logs with kubectl logs.

But still, I'm unsure is a Kubernetes CronJob a better solution, or there is some third option?

Author

I plan to write more articles about common laravel components. If you are interested let’s stay in touch.
comments powered by Disqus