Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
The Permission Denied error in Laravel is one of the most frustrating problems that developers and DevOps/SRE teams can encounter when working with the Laravel framework. This problem usually occurs due to incorrect permissions settings for files and directories related to Laravel logs, especially in production environments. In this article, we’ll explore the main causes and present definitive solutions to resolve this error and avoid downtime in your PHP application.
Table of Contents
Laravel is a popular framework used by many developers to create PHP web applications. A common problem that can occur when working with Laravel is the error:
The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: permission denied
This error occurs when Laravel cannot write to its log file because it does not have permission to access the storage folder.
Another very common error, which can happen when we do not have the permissions defined correctly in Laravel, is the error below:
Error in exception handler: The stream or file "/var/www/laravel/app/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /var/www/laravel/bootstrap/compiled.php:8423
One solution that is recommended in many forums and blogs is to apply the chmod 777
permission, which ends up leaving our server very exposed.
In some cases, other commands are suggested, such as chmod, chgrp, which may not make the server less secure
but do not provide a definitive solution to permission errors in Laravel.
This error Laravel The stream or file
occurs when Laravel cannot write to its log file because it is not permitted to access the storage folder.
Fortunately, there is a relatively easy solution to this problem. You can apply permissions and inheritance to the permissions in the /var/www/html/storage/logs
folder on the server.
To do this, you’ll need to access the server where Laravel is hosted and run a few commands in the project folder (in this example we’re using /var/www/html/
).
Another important point is that I try to add the users who work with Laravel to the www-data
group, so that after applying the solution they can manipulate the files without causing problems and new permission errors in Laravel.
Here is the script we should use, adapt it to your needs:
## laravel log permission
cd /var/www/html/
sudo chgrp -R www-data bootstrap/ storage/ storage/logs/
sudo chmod -R 755 bootstrap/ storage/ storage/logs/
sudo chmod -R g+w bootstrap/ storage/ storage/logs/
cd bootstrap/
sudo find -type d -exec chmod g+s {} +
cd ..
cd storage/
sudo find -type d -exec chmod g+s {} +
cd ..
cd storage/logs/
sudo find -type d -exec chmod g+s {} +
This Bash script is used to grant correct permissions to the bootstrap/
, storage/
and storage/logs/
directories of a Laravel project that is located in /var/www/html/
. Specifically, the script sets the owner group of these directories to www-data, which is the default user and group of the web server on Ubuntu. In addition, the script ensures that these directories have write permissions for the www-data
group.
The part of the script that refers to the inheritance of permissions is the following line:
sudo find -type d -exec chmod g+s {} +
This line sets the SGID bit in all directories within the bootstrap/
, storage/
and storage/logs/
directories. When the SGID bit is set on a directory, it ensures that all new files created within that directory inherit the ownership group of the parent directory. This is useful to ensure that all files created within the bootstrap/
, storage/
and storage/logs/
directories have the same ownership group(www-data
) and can therefore be read and written to by the web server.
In summary, the script performs the following actions:
sudo: the sudo command is used to execute commands with superuser (root) privileges in the Linux or Unix operating system.
chgrp: the chgrp command is used to change the ownership group of a file or directory.
-R: is an option for the chgrp command that means “recursively”. It causes the command to be run on all directories and subdirectories below the current directory.
In short, the sudo chgrp -R command recursively changes the ownership group of all files and directories below the current directory.
The 755 permission is a permissions setting commonly used in Unix-based operating systems such as Linux and macOS. It defines the following access levels:
This means
sudo
: The sudo command allows you to temporarily execute commands with administrator (root) privileges on Unix/Linux systems, requiring a password for authorization.
chmod
: is a command that is used to change the access permissions of a file or directory.
-R
: same as above
g+w
: is an option for the chmod command which means “add write permission for the group”. “g” is the group that owns the file or directory.
In short, the sudo chmod -R g+w command adds write permission for the owner group to all files and directories below the current directory.
sudo
: same as above
find
: is a command used to find files and directories based on specific criteria.
-type d
: is an option for the find command which means “find directories only”.
-exec
: is an option for the find command that executes a command on each file or directory found.
chmod g+s
: is the command that will be executed on each directory found by find. “g” is the group that owns the directory and “s” is an option that means “set the setgid bit”. This causes all files created within the directory to inherit the directory’s owner group.
{}
: is a placeholder for the name of the file or directory found by find.
+
: indicates that the chmod g+s
command should be run once for each group of files or directories found.
In summary, the command sudo find -type d -exec chmod g+s {} +
finds all the directories below the current directory and executes the command chmod g+s on each of them, ensuring that all files created within these directories have the same ownership group.
Here in my lab I like to use the Travellist – Laravel Demo App project, which uses the Laravel PHP framework, to practice the installation and basic use of Laravel. It builds an example travel list application, to show a list of places a user would like to travel to and a list of places they have already visited.
After uploading the project and accessing it via Browser, this is the page that is displayed:
As you can see in the image below, the files and folders have their permissions set correctly and the Containers are working as expected:
One directory that is very important, as it stores all of Laravel’s logs, is the storage/logs directory
Checking the permissions of this directory and the directories inside the:
Permission errors in Laravel and its storage directory or in the logs directory can lead to crashes in your application and the occurrence of “Permission denied” errors related to the /var/www/storage/logs folder.
In the example below, I am incorrectly setting the permissions on the storage directory to force the permission error to occur:
With the permissions set incorrectly, if I try to access the Travellist page again in my local environment, the following error occurs:
Error message:
UnexpectedValueException
There is no existing directory at "/var/www/storage/logs" and its not buildable: Permission denied
To regularize the permissions of the storage directory and the directories below it, I ran the following commands:
docker exec -u 0 -it travellist-app /bin/bash
chgrp -R www-data storage/ storage/logs/
chmod -R 755 storage/ storage/logs/
chmod -R g+w storage/ storage/logs/
cd storage/
find -type d -exec chmod g+s {} +
It is important to note that, in this case, I used a Docker command to access the container as the root user, in order to be able to apply these commands, according to the parameter:
-u 0
: Specifies the user ID(0 is the root ID)
No errors should occur during the application of the commands, as shown below:
After applying the commands, access to the Laravel project page is restored:
The Laravel Permission Denied error may seem complicated, but the solutions are straightforward once you understand how the permissions system works. Correctly configuring the storage and bootstrap/cache directories, adjusting the user and group, and ensuring that permissions are not modified inappropriately are fundamental steps to prevent this error from disrupting the functioning of the project.
More troubleshooting tips? Visit: Troubleshooting
I always get this error when deploy my laravel app using docker, why is it happen?
Hello,
Have you tried adjusting the permissions?
Is it possible to adjust the Dockerfile so that the permissions are always correct? Have you already applied changes to your Dockerfile?