When using Supervisor to run your Laravel queue workers in the background, you may run into the issue of your application crashing due to being unable to write to the log files. That is because when a log file is created by the queue worker that is executed by Supervisor, it is created by the root user. When your application tries to write to the same log file, it crashes because the user that attempts to write to the log files does not have permissions to do so, unless it is a root user.
There are multiple solutions to this and I will go through three of them.
This is aimed at CentOS web servers. It may work on other Linux distributions as well.
- Run the queue worker with supervisor as a different user.
- Create different log files for different users.
- Change the ownership of log files.
Run the queue worker with supervisor as a different user
When configuring Supervisor to run your Laravel queue worker, you can specify a user to run the process as.
$ nano /etc/supervisord.conf [program:the-program-name] user=the-user-name
See the Supervisor Configuration section in the Laravel documentation for more information.
This works but there is a catch.
The log files are created as the user you specify in supervisor’s configuration. Your application will no longer crash because it is able to write to the log files but a new issue arises. If all your configuration is stored in the .env file, it will not be available for your Laravel application to use when executed by the Supervisor worker. Laravel will still however use the cached configuration until it is cleared, then fall back to the configuration stored in your Laravel application’s config directory.
If you do not make use of the .env file, your Laravel application will work normally.
This is what I know. The child process that gets executed by supervisor to execute and run your queue worker does not run in a fully configured shell environment. It is unable to read your Laravel application’s .env file. Somehow it affects the way your Laravel application makes use of the .env outside of Supervisor’s worker and causes your application to crash when you clear the cache. I have not yet determined why this is happening.
You can find a better solution below.
Create different log files for different users
Run the Laravel application’s queue worker with Supervisor as the root user.
Change your application’s logging config file to create daily log files based on the user that executes the script.
$ nano config/logging.php return [ 'channels' => [ ..., 'daily' => [ ..., 'path' => storage_path('logs/laravel-'.php_sapi_name().'.log'), ... ], ... ] ];
Here is an example of the log files it creates.
-rw-r--r-- 1 root root 43K Jun 26 19:00 laravel-cli-2019-06-26.log -rw-r--r-- 1 user user 43K Jun 26 19:00 laravel-cgi-fcgi-2019-06-26.log
It does not matter who created the log files. All users will have their own log files thus averting the log file writing permissions issue outlined above.
I have gone with a different solution which you can find below.
Changing the ownership of log files
The last solution I want to add it to update the ownership of the log files every 5 minutes.
While accessing the server you are running Supervisor on as root, add the following cronjob. It will automatically change the ownership of the log files in the specified directory.
$ crontab -e */5 * * * * chown user:group /home/user/laravel-app/storage/logs/*.log > /dev/null 2>&1
By adding the cronjob to your crontab, the system will automatically change the ownership of all log files in the log directory. Laravel normally have a 14 day log file retention which can be increased or decreased. You should never experience any downtime but if you do, it will be a maximum of 5 minutes.