На главную | Автор

Как в Laravel автоматически запускать код по расписанию?

Для чего? Для того чтобы пользоваться планировщиком crond и запускать команды из ларавел-фреймворка.

Выполни команду php artisan make:console MyCommand (Cмотри доку и далее пропиши в файле app/Console/Kernel.php метод:

Php картиночка
  
  // Это файл app/Console/Kernel.php
  // Но просто так этот код не выполнится, его надо "дёрнуть из крона"
  protected function schedule(Schedule $schedule)
  {
  $schedule->command('my:command')->everyMinute();
  }
  

Теперь собирай docker-образ (docker image) с таким кодом. Учти некоторые детали опущены, я вывожу только самое основное что касается настройки.

  
  // Dockerfile
  // я не любитель debian, но это всё для примера
  FROM php:7.4-fpm-bullseye

  // Тут твой софта RUN apt-get .....

  // Тут мои советы начинаются
  RUN apt-get update && apt-get install -y cron  \
  && apt-get purge -y g++ \
  && apt-get autoremove -y \
  && rm -r /var/lib/apt/lists/*

  // Отнесись к этому внимательно, если твой основной образ и PHP в нём работает
  // от пользователя с uid=1000, то ничего в нём не меня. Иначе уточни uid
  // такой uid по-умолчанию создаётся в linux когда по умолчанию создают не-рутового юзера
  // например когда у тебя в системе только root и твой юзер , тогда у твоего юзера будет uid=1000
  // при условии что ты его не создавал специально с другим uid. Этот uid юзер твоей хостовой системы.
  RUN adduser --system --uid 1000 --quiet --no-create-home --disabled-password app

  // Далее предполагаю что у тебя есть свой crontab файли для laravelа.
  // Этот файлик клади рядом с Dockerfile
  // Содержимое файлика будет ниже
  COPY ./crontab /crontab

  // Теперь задавай расписание для своего докеровского юзера
  // таким образом всё что прописано в твоём crontab будет выполняться из-под app пользователя (из под uid = 1000)
  RUN cat /crontab | crontab -u app -

  // Эта магия может пригодится, вдруг crond потребует лог файл и без него не захочет запускаться
  // под каждый crond разный путь, для этого image прокатывает такой (наверное, не уверен что это нужно)
  RUN touch /var/log/cron.log

  // Это может потребоваться для крона, т.к в кроне нет терминала и переменные окружения ему неизвестны
  // но и без этого можно обойтись. Я на всякий это оставляю.
  RUN export SHELL=/bin/bash && export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

  // крон запускаем в foreground режиме
  ENTRYPOINT ["/usr/sbin/cron", "-f"]

Теперь внимательно отнесись к файлу crontab его содержимое ниже

  
    # min	hour	day	    month	weekday  command
  *     *       *       *       *        /bin/bash -c '/usr/local/bin/php /абсолютный-путь-до/artisan schedule:run'
  # Обязательный комментарий (EOF здесь)
  

Абсолютный путь до artisan и путь до php пропиши сам. Лучше прописывать абсолютные значения.

Теперь твой crond сможет запускать код ларавела (который мне на самом деле не очень нравится, но тем не менее).
Надеюсь тебе это помогло!

Если вдруг столкнулись с такой ошибкой:

  
    Did you mean this?
    schedule:run at /app/vendor/symfony/console/Application.php:651)
  

То обязательно нужно проверить кодировку файла crontab. Т.к если у вас windows, то в некоторых случаях может быть что ваш crontab файл имеет другую кодировку и при переносе файла в Docker-образ происходит "кривое считывание файла" программой crond