I'm currently build an app using laravel, that I am only going to run locally using Docker, however, I do need to run the scheduler, so I started looking into how to run crons within the docker container.
I came across a few different ways of doing, from people who clearly know more about Docker than I do, however, I am going to share the way that I was able to get it to work.
Below is what you need (at a minimum) to get the cron service running within your docker container.
FROM php:7.1-fpm
WORKDIR /var/www
RUN apt-get update
RUN apt-get install -y \
cron
# Create the log file
RUN touch /var/log/schedule.log
RUN chmod 0777 /var/log/schedule.log
# Add crontab file in the cron directory
ADD scheduler /etc/cron.d/scheduler
# Run the cron
RUN crontab /etc/cron.d/scheduler
CMD ["cron", "-f"]
Lets break this down, firstly we need to pull in cron
using apt-get
so that we have what we need
to run the crons.
Next, and this is optional, we create a file for the cron logs to be stored into.
We then add the cron to the crontab, by storing the cron in a file called scheduler
(in
the same folder as your docker file), which just contains a standard crontab command.
* * * * * su -c 'php /var/www/artisan schedule:run >> /var/log/schedule.log 2>&1'
These commands, then add it to the crontab in the docker:
ADD scheduler /etc/cron.d/scheduler
RUN crontab /etc/cron.d/scheduler
And then all we need to do is run the cron command with CMD ["cron", "-f"]
.
Now, I do need to add one issue I ran into with this. I first tried adding this into my php container, and allow it does work, and the crons where running, for some reason, that I couldn't figure out, it prevented the app it self from loading in the browser.
To get around this, I simply copied by php docker file, and created a cron docker file. So my docker-compose.yml
file looks like this:
version: '2'
services:
php:
build: ./docker/php
volumes:
- .:/var/www
links:
- mysql
cron:
build: ./docker/cron
volumes:
- .:/var/www
links:
- mysql
redis:
build: ./docker/redis
volumes:
- redisdata:/data
links:
- php
nginx:
build: ./docker/nginx
ports:
- "8008:80"
volumes:
- .:/var/www
links:
- php
depends_on:
- php
mysql:
ports:
- "33060:3306"
image: 'mysql:5.6'
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=tasks
volumes:
- mysqldata:/var/lib/mysql
volumes:
mysqldata:
driver: "local"
redisdata:
driver: "local"