How can I configure Supervisor and scheduling with Laravel Sail?
Asked Answered
C

6

7

I'm using Laravel sail. I want to use supervisor and cronjob. But I don't understand how I can configure these things with sail.

I can't find any examples on how to do this.

Chanukah answered 1/6, 2021 at 20:31 Comment(2)
Did you find the answer? can you share it if you have?Crescen
I found a solution for only queues that is below and it works with queues, not cronjobs. After adding these codes your supervisor.conf file you must restart containers with docker-compose up ---build https://mcmap.net/q/1452521/-how-can-i-configure-supervisor-and-scheduling-with-laravel-sail @CrescenChanukah
Y
5

Laravel Sail is designed as a development environment and as such I believe Laravel have purposefully omitted automatic running of cron jobs and queue workers in favour of giving developers control over running them using the appropriate artisan commands.

To use the Laravel Scheduler inside Sail you can simply run:

sail artisan schedule:work

This command will run in the foreground and invoke the scheduler every minute until you terminate the command.

Similarly, if you want to run the Queue worker inside Sail you can run the following:

sail artisan queue:work

Running these commands locally gives the developer complete control rather than having tasks and queues running automatically inside the container.

I would strongly recommend sticking with running these commands manually so that your app doesn't unexpectedly fire out a million emails that are sat in the queue or run other unintended jobs or tasks!

If, against this advice, you did want to have the Laravel scheduler run automatically inside the Sail docker container then the steps would be something like this:

  1. Publish the Sail docker assets using sail artisan sail:publish
  2. Edit the Dockerfile to add the cron package e.g. RUN apt-get install -y cron
  3. Edit the Dockerfile to create an appropriate cron job in /etc/cron.d/laravel
  4. Edit the Dockerfile to start the cron service e.g. RUN /usr/sbin/service cron start
  5. Rebuild the Sail docker container with sail build --no-cache

Similarly, after publishing the Sail assets you could also edit the provided supervisord.conf to automatically run queues using supervisord.

Yarborough answered 24/2, 2022 at 10:27 Comment(3)
I agree that adding a scheduler to sail doesn't seem right.Ambagious
@Ambagious not really if you are trying to test environments that is the purpose of docker to run the same setup as your production environments. If you don't have that running then you will never know that things arent working properly, which is critical to understanding on a local environment. Example, a feature that uploads csv of thousands of records, you will have jobs that do service logic in the background.Instancy
@Instancy that may be one purpose of docker but it certainly is not the purpose of sail which is a tool for interacting with Laravel's default Docker development environment.Yarborough
T
4
  1. Execute php artisan sail:publish, it will publish a docker directory in your project root directory.

  2. Add the scheduler/crontab file into the docker runtime folder (i.g: docker/8.2/scheduler)

* * * * * root cd /var/www/html && php artisan schedule:run --no-interaction >> /var/www/html/storage/logs/cron.log 2>&1
  1. Update docker/8.2/Dockerfile
  • before && apt-get install -y yarn \ add && apt-get install -y cron \
  • after RUN useradd -ms /bin/bash ..., add the following lines:
COPY scheduler /etc/cron.d/scheduler
RUN chmod 0644 /etc/cron.d/scheduler \
    && crontab /etc/cron.d/scheduler
  1. Update docker/8.2/supervisord.conf file, by adding the following lines:
[program:cron]

    command=/usr/sbin/cron -f -l 8
    autostart=true
    stdout_logfile=/var/log/cron.out.log
    stderr_logfile=/var/log/cron.err.log

And the following if you want to run horizon too:

[program:horizon]

    process_name=%(program_name)s
    command=/usr/bin/php /var/www/html/artisan horizon
    autostart=true
    autorestart=true
    user=sail
    redirect_stderr=true
    stdout_logfile=/var/www/html/storage/logs/horizon.log
    stopwaitsecs=360

Torero answered 13/6, 2023 at 8:44 Comment(2)
Thank you for the post. Now I understand how to customize the docker images for testing. FWIW, after customizing please be sure to rebuild the image using sail build --no-cache see laravel.com/docs/10.x/sail#sail-customization. Also, I later found out the using the php artisan schedule:work command locally meets my needs for local development: laravel.com/docs/10.x/scheduling#running-the-scheduler-locally)Frankish
There is an issue with your code crontab /etc/cron.d/scheduler, it fails with the error that scheduler is not an actual file. It is actually a directory. It is supposed to be crontab /etc/cron.d/scheduler/crontab, yes?.Carnet
O
2

Because sail uses a Ubuntu container you can follow these instructions: https://serverspace.io/support/help/automate-tasks-with-cron-ubuntu-20-04/

Typically they are stored in /var/spool/cron/crontabs so you might want to create a volume to persist them (otherwise they will be removed on the next restart of your container).

You can connect to your container with docker-compose exec laravel.test bash I believe.


Supervisord is already installed

Observer answered 2/6, 2021 at 10:11 Comment(0)
L
1

You can follow these steps:

  1. Check your docker-compose.yml file to find laravel.test -> build -> context to ensure sail package. Exp: ./vendor/laravel/sail/runtimes/8.2
  2. Create a directory beside app directory and copy sail runtimes files to it. Exp: sail.
  3. Edit supervisord.conf file in created directory sail and add these lines:

[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid

[program:php]
command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80
user=sail
environment=LARAVEL_SAIL="1"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[include]
files = /var/www/html/supervisor/*.conf

You can create supervisor directory and put your supervisor config file into it.

You should run ./vendor/bin/sail down and ./vendor/bin/sail build to rebuild your configs then you can run ./vendor/bin/sail up -d to up containers.

Leprose answered 28/4, 2023 at 17:0 Comment(0)
C
0

I solved my problem another way. I added this codes to sail's supervisor.conf file.

process_name=%(program_name)s
command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan horizon
user=sail
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/www/html/horizon.log
stopwaitsecs=3600

[program:cron-job]
process_name=%(program_name)s
command=crond -f
user=root           ; crond should be started as root at all times
autostart=true
autorestart=true
numprocs=1
redirect_stderr=false
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

Maybe it is not best solution but it's worked.

Chanukah answered 12/8, 2021 at 22:39 Comment(0)
A
-1

To setup Supervisor for Laravel queues, this is what I tried within the Docker container for Laravel Sail.

To enter the container:

docker-compose exec laravel.test bash

Run inside the container:

apt update
apt install nano
cd /etc/supervisor/conf.d
touch laravel-worker.conf
nano laravel-worker.conf

Paste in:

[supervisord]
nodaemon=false
user=root
logfile=/var/log/supervisor/laravel-worker.log
pidfile=/var/run/laravel-worker.pid

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=sail
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/worker.log
stopwaitsecs=3600
startsecs=0

[supervisorctl]

Save with Nano:

ctrl + o
ctrl + x

To run the queue workers:

supervisord -c /etc/supervisor/conf.d/laravel-worker.conf

To restart the queue workers if your application code changes:

service supervisor restart

Remember, queue workers, are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers. In addition, remember that any static state created or modified by your application will not be automatically reset between jobs. Queues - Laravel - Running the Queue Worker

Note: if the Docker container is restarted, you'll need to manually run the supervisord command again.

From digging into Laravel Sail a bit, it looks like you shouldn't change /etc/supervisor/conf.d/supervisord.conf since it's so tied into Docker. For example, if the supervisor process is killed, the container stops i.e. the webserver stops and you're logged out. This makes it more difficult to change the queue worker configuration since it requires restarting the process.

See sail/runtimes/8.0/start-container.

Final thoughts: Overall, if I had to start over again knowing what I know now, I might have configured Supervisor (and cron) outside of the Docker container on the host system. It's less complicated and probably less prone to breaking in the future in case of Sail updates.

Alberik answered 11/8, 2021 at 7:22 Comment(1)
I tried similar method but it's not permanent.Chanukah

© 2022 - 2025 — McMap. All rights reserved.