serversideup / docker-php

🐳 Production-ready Docker images for PHP. Optimized for Laravel, WordPress, and more!
https://serversideup.net/open-source/docker-php/
GNU General Public License v3.0
1.65k stars 108 forks source link

Scheduler not working with S6 in new V3 images #370

Closed MasterZydra closed 3 months ago

MasterZydra commented 3 months ago

Affected Docker Images

serversideup/php:8.3-fpm-apache

Current Behavior

I use the S6 overlay to run the laravel scheduler. Back in V2 of the image that worked without issues. With the upgrade to V3 the scheduler is still executed but it cannot start a new artisan command. The error message is: "Could not open input file: artisan".

Expected Behavior

The artisan file is found.

Steps To Reproduce

Dockerfile:

    # Add start of laravel schedule
RUN mkdir -p /etc/s6-overlay/s6-rc.d/laravel-schedule ; \
    echo "#!/usr/bin/bash" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/run ; \
    echo "php /var/www/html/artisan schedule:work --run-output-file=/var/www/html/schedule.log" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/run ; \
    echo "longrun" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/type ; \
    echo "50-laravel-automations" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/dependencies ; \
    touch /etc/s6-overlay/s6-rc.d/user/contents.d/laravel-schedule

app/Console/Kernel.php:

    protected function schedule(Schedule $schedule): void
    {
        $schedule->call(function() {
            Artisan::call('test:command');
        })->everyFiveMinutes();
    }

The file "/var/www/html/schedule.log" will contain the message "Could not open input file: artisan" for every attempt of the scheduler to execute the the command "php artisan test:command".

Anything else?

I fixed it by defining the constant "ARTISAN_BINARY".

app/Console/Kernel.php:

    public function __construct(
        \Illuminate\Contracts\Foundation\Application $app,
        \Illuminate\Contracts\Events\Dispatcher $events
    ) {
        if (! defined('ARTISAN_BINARY')) {
            define('ARTISAN_BINARY', '/var/www/html/artisan');
        }

        parent::__construct($app, $events);
    }

I don't understand what changed in the Docker image that makes it necessary to make the path absolute.

jaydrogers commented 3 months ago

You need to ensure you're copying the artisan file and all other Laravel files with the proper permissions:

COPY --chown=www-data:www-data . /var/www/html

See this example for more: https://serversideup.net/open-source/docker-php/docs/guide/migrating-from-v2-to-v3#cicd

If you have further questions, please open up a "Q&A" discussion item under "Discussions" instead of "Issues": https://github.com/serversideup/docker-php/discussions

jaydrogers commented 3 months ago

Also, since you're writing your own S6 service, you may want to look into calling docker-php-serversideup-s6-init https://serversideup.net/open-source/docker-php/docs/customizing-the-image/adding-your-own-start-up-scripts#docker-php-serversideup-s6-init-usage

MasterZydra commented 3 months ago

You need to ensure you're copying the artisan file and all other Laravel files with the proper permissions:

COPY --chown=www-data:www-data . /var/www/html

See this example for more: https://serversideup.net/open-source/docker-php/docs/guide/migrating-from-v2-to-v3#cicd

If you have further questions, please open up a "Q&A" discussion item under "Discussions" instead of "Issues": https://github.com/serversideup/docker-php/discussions

Thanks for the fast reply.

I have only copied a part of my dockerfile in the description above, sorry. In the dockerfile I copy the whole laravel project including artisan and fix the permission.

FROM serversideup/php:8.3-fpm-apache

WORKDIR /var/www/html

COPY . .

USER root

RUN apt-get update ; \
    apt-get -y upgrade ; \
    # Rename env.example so that .env exists
    cp .env.example .env ; \
    # Fix permissions
    chown -R www-data:www-data /var/www/html ; \
    # Add start of laravel schedule
    mkdir -p /etc/s6-overlay/s6-rc.d/laravel-schedule ; \
    echo "#!/usr/bin/bash" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/run ; \
    echo "php /var/www/html/artisan schedule:work --run-output-file=/var/www/html/schedule.log" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/run ; \
    echo "longrun" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/type ; \
    echo "50-laravel-automations" >> /etc/s6-overlay/s6-rc.d/laravel-schedule/dependencies ; \
    touch /etc/s6-overlay/s6-rc.d/user/contents.d/laravel-schedule

USER www-data

EXPOSE 8080

I have found the issue after reviewing my changes again: Before:

cd /var/www/html && php /var/www/html/artisan schedule:work --run-output-file=/var/www/html/schedule.log

After

php /var/www/html/artisan schedule:work --run-output-file=/var/www/html/schedule.log