Laravel Docker #4 - Setting up Scheduler (Cron Jobs)
Sometimes in Laravel projects, you may need to run tasks automatically at a fixed time. For example, sending daily emails or clearing old data. Laravel provides a scheduler feature for this purpose.
In this tutorial, I will show you how to set up the Laravel scheduler inside Docker. We will use Nginx, PHP, MySQL, and an extra service for running the schedule command every minute.
Step 1: Create Laravel Project
First, let’s create a new Laravel project. Run the below command:
laravel new my-app
Step 2: Create Dockerfile
Next, create a Dockerfile that will install PHP and Composer inside the container.
Dockerfile
FROM php:8.3-fpm
WORKDIR /var/www/html
RUN apt-get update & apt-get install -y \
libzip-dev \
unzip \
& docker-php-ext-install zip pdo_mysql
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY . /var/www/html
# Install PHP dependencies
RUN composer install
RUN chown -R www-data:www-data /var/www/html
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache /var/www/html/vendor
RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache /var/www/html/vendor
EXPOSE 80
Step 3: Create NGINX Config File
Now, create an Nginx config file. This will handle the Laravel public directory and PHP requests.
.docker/apache/default.conf
server {
listen 80;
index index.php index.html;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass web:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
location ~ /\.ht {
deny all;
}
}
Step 4: Create docker-compose.yml
Finally, create a docker-compose.yml file. This will set up web, nginx, db, and also a scheduler service for cron jobs.
docker-compose.yml
services:
web:
build:
context: .
dockerfile: Dockerfile
image: my-laravel-app
volumes:
- .:/var/www/html
- /var/www/html/storage
- /var/www/html/bootstrap/cache
- /var/www/html/vendor
working_dir: /var/www/html
user: "www-data"
depends_on:
- db
nginx:
image: nginx:latest
ports:
- "8080:80"
volumes:
- .:/var/www/html
- ./.docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- web
scheduler:
build:
context: .
dockerfile: Dockerfile
image: my-laravel-app
volumes:
- .:/var/www/html
working_dir: /var/www/html
command: ["sh", "-c", "while [ true ]; do php artisan schedule:run --verbose --no-interaction; sleep 60; done"]
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
ports:
- "3307:3306"
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
Run Laravel App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:
php artisan serve
Now, Go to your web browser, type the given URL and view the app output:
http://localhost:8080
Now you can use.