Permission denied ".../storage/logs/laravel.log could not be opened" #370

Closed
opened 2026-02-04 19:09:25 +03:00 by OVERLORD · 19 comments
Owner

Originally created by @viewty on GitHub (Jul 14, 2017).

Project Maintainer Edit - For Laravel Developers

Gaining an understanding of Unix permissions, rather than blindly setting them.
Please see the comment here: https://github.com/BookStackApp/BookStack/issues/436#issuecomment-395964366

Original Issue

Hi all,

Having a permissions problem with the install. I'll try to provide all the necessary info if some one could please help.

For Bug Reports

  • BookStack Version: v0.17.1
  • PHP Version: 7.0.20
  • MySQL Version: 14.14 Distrib 5.6.36
Expected Behaviour

Redirected after login

Actual Behaviour

HTTP Error 500

[root@core]# tail /var/log/httpd/error_log
PHP Fatal error:  Uncaught UnexpectedValueException: The stream or file "/home/bookstack/bookstack/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107\nStack trace:\n#0 /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\\Handler\\StreamHandler->write(Array)\n#1 /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\\Handler\\AbstractProcessingHandler->handle(Array)\n#2 /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Logger.php(616): Monolog\\Logger->addRecord(400, Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)\n#3 /home/bookstack/bookstack/vendor/laravel/framework/src/Illuminate/Log/Writer.php(203): Monolog\\Logger->error(Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)\n#4 /home/bookstack/bookstack/vendor/laravel/framework/src/Illuminate/Log/Writer.php(114): Illum in /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107, referer: http://docs.someurl.co/login

I go to docs.someurl.co and I am shown the login page. Great. I put in admin@admin.com and password and I get a HTTP Error 500.

[root@core bookstack]# pwd
/home/bookstack/bookstack
[root@core bookstack]# ls -all | grep storage
drwxr-xr-x  7 bookstack bookstack     69 Jul 13 17:01 storage
[root@core bookstack]# cd storage
/home/bookstack/bookstack/storage
[root@core storage]# ls -all
total 4
drwxr-xr-x  7 bookstack bookstack   69 Jul 13 17:01 .
drwxr-xr-x 14 bookstack bookstack 4096 Jul 13 17:27 ..
drwxr-xr-x  2 bookstack bookstack   23 Jul 13 17:01 app
drwxr-xr-x  2 bookstack bookstack   23 Jul 13 17:01 fonts
drwxr-xr-x  5 bookstack bookstack   62 Jul 13 17:01 framework
drwxr-xr-x  2 bookstack bookstack   23 Jul 14 09:55 logs
drwxr-xr-x  3 bookstack bookstack   18 Jul 13 17:01 uploads
Originally created by @viewty on GitHub (Jul 14, 2017). ## Project Maintainer Edit - For Laravel Developers Gaining an understanding of Unix permissions, rather than blindly setting them. Please see the comment here: https://github.com/BookStackApp/BookStack/issues/436#issuecomment-395964366 ## Original Issue Hi all, Having a permissions problem with the install. I'll try to provide all the necessary info if some one could please help. ### For Bug Reports * BookStack Version: v0.17.1 * PHP Version: 7.0.20 * MySQL Version: 14.14 Distrib 5.6.36 ##### Expected Behaviour Redirected after login ##### Actual Behaviour HTTP Error 500 ``` [root@core]# tail /var/log/httpd/error_log PHP Fatal error: Uncaught UnexpectedValueException: The stream or file "/home/bookstack/bookstack/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107\nStack trace:\n#0 /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\\Handler\\StreamHandler->write(Array)\n#1 /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\\Handler\\AbstractProcessingHandler->handle(Array)\n#2 /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Logger.php(616): Monolog\\Logger->addRecord(400, Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)\n#3 /home/bookstack/bookstack/vendor/laravel/framework/src/Illuminate/Log/Writer.php(203): Monolog\\Logger->error(Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)\n#4 /home/bookstack/bookstack/vendor/laravel/framework/src/Illuminate/Log/Writer.php(114): Illum in /home/bookstack/bookstack/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107, referer: http://docs.someurl.co/login ``` I go to docs.someurl.co and I am shown the login page. Great. I put in `admin@admin.com` and `password` and I get a HTTP Error 500. ``` [root@core bookstack]# pwd /home/bookstack/bookstack [root@core bookstack]# ls -all | grep storage drwxr-xr-x 7 bookstack bookstack 69 Jul 13 17:01 storage [root@core bookstack]# cd storage /home/bookstack/bookstack/storage [root@core storage]# ls -all total 4 drwxr-xr-x 7 bookstack bookstack 69 Jul 13 17:01 . drwxr-xr-x 14 bookstack bookstack 4096 Jul 13 17:27 .. drwxr-xr-x 2 bookstack bookstack 23 Jul 13 17:01 app drwxr-xr-x 2 bookstack bookstack 23 Jul 13 17:01 fonts drwxr-xr-x 5 bookstack bookstack 62 Jul 13 17:01 framework drwxr-xr-x 2 bookstack bookstack 23 Jul 14 09:55 logs drwxr-xr-x 3 bookstack bookstack 18 Jul 13 17:01 uploads ```
Author
Owner

@ssddanbrown commented on GitHub (Jul 14, 2017):

Hi @viewty,
This looks like a fairly standard permission error.

The storage folder and bootstrap/cache folders need to be writable by the webserver user/group. Usually this is often the user/group www-data but it depends on your setup.

What http server are you using (Apache or nignx?) and what OS are you running BookStack on?

@ssddanbrown commented on GitHub (Jul 14, 2017): Hi @viewty, This looks like a fairly standard permission error. The `storage` folder and `bootstrap/cache` folders need to be writable by the webserver user/group. Usually this is often the user/group `www-data` but it depends on your setup. What http server are you using (Apache or nignx?) and what OS are you running BookStack on?
Author
Owner

@viewty commented on GitHub (Jul 14, 2017):

Not sure what was going on - restarted httpd and that problem is solved.

This is with Apache on Centos 7.

I had previously done chmod 777 -R storage bootstrap/cache public/uploads but I might have made a typo.

Thanks for the quick reply and help.

@viewty commented on GitHub (Jul 14, 2017): Not sure what was going on - restarted httpd and that problem is solved. This is with Apache on Centos 7. I had previously done `chmod 777 -R storage bootstrap/cache public/uploads` but I might have made a typo. Thanks for the quick reply and help.
Author
Owner

@yemiwebby commented on GitHub (May 10, 2018):

chmod -R 777 storage worked for me

@yemiwebby commented on GitHub (May 10, 2018): `chmod -R 777 storage` worked for me
Author
Owner

@hariDasu commented on GitHub (Jun 8, 2018):

chmod -R 775 storage worked for me

@hariDasu commented on GitHub (Jun 8, 2018): `chmod -R 775 storage` worked for me
Author
Owner

@ssddanbrown commented on GitHub (Jun 9, 2018):

Lol, This is the most popular page of all BookStack GitHub pages.

Hello fellow Laravel developers who have googled their writable storage issues. It's important to be aware of what permissions you are setting so I thought I'd provide a little overview. Better, more detailed guides are available via more googling.

Unix-Style Permissions

Files and folders have 3 main permissions: read, write & execute.
Files and folders are also assigned an owner and group.

Reading Permissions

You can run ls -alh in the terminal to show the files and folders with their permissions:

# ls -alh
drwxrwxr-x  5 dan      dan 4.0K May 28 13:58 .
drwxrwxr-x 18 dan      dan 4.0K Jun  9 10:38 ..
-rw-r--r--  1 dan      dan 5.6K Dec 10 18:19 book_default_cover.png
drwxr-xr-x  2 dan      dan 4.0K Jun  9 10:40 dist
-rw-rwxr--  1 www-data dan  11K Oct 26  2016 favicon.ico
-rw-r--r--  1 dan      dan  412 Aug  9  2017 .htaccess

The permissions are on the left, in the first column. The starting d is shown if it's a directory. Then there are three sets of rwx.

  • The first set of rwx is the permissions for the owner.
  • The second set of rwx is the permissions for the group.
  • The third set of rwx is the permissions for everyone else.

Each of these characters represents read, write or execute. A hyphen (-) is shown instead if the permission is not granted. Note that execute permissions are required on folders to enter them.

The owner assigned to a file/folder can be seen in the third column. The group can be seen in the fourth. In the example above the file favicon.ico is assigned to the group dan and is owned by www-data. The owner www-data has permission to read and write the file. The group dan has permission to read, write, or execute the file. Everyone else can only read the file.

Octal Format

Permissions may also be shown as numbers in an octal format. In the octal format each permission has a number:

  • Read = 4
  • Write = 2
  • Execute = 1
  • No permission = 0

These numbers are summed together into a single digit. For example, Having all permissions will be shown as a 7 or only having Read+Execute permissions will be shown as a 5. These totals are often used in a set of 3 to represent the permissions for the group, owner & everyone else.

In the example command output above, the permissions for favicon.ico could be shown as 674. The .htaccess file permissions could be shown as 644. All permissions granted to everyone would show as 777.

Setting Permissions

There are two main commands for controlling permissions:

  • chmod (Change mode), Used to set permissions.
  • chown (Change ownership), Used to change the owner and group.

For both of these commands using -R will set permissions recursively upon all child files and directories.

chmod usage

# Format:
chmod [OPTIONS] PERMISSONS FILES...

# Example:
# Grant the owner and group 'read+write+execute' permissions
# Give everyone else 'read and execute' permissions
# In the './storage' directory and all files+folders within.
chmod -R 775 ./storage 

chown usage

# Format:
chown [OPTIONS] USER:GROUP

# Example:
# In the './storage' directory and all files+folders within
# Set the owner to be 'dan' and set the group to be 'www-data'
chown -R dan:www-data ./storage 

Common use

For things such as file uploads, you'd generally want these to be both readable and writable by the webserver. The user and group your web server runs as will depend on your system and config. On ubuntu it's common for apache and nginx to run as www-data, both as the owner and group. In this case, If i wanted to give the webserver permission to upload and serve files within the ./storage directory I might do the following:

# Recursively set myself as the owner and the web server as the assigned group
chown -R dan:www-data ./storage

# Recursively allow myself and the webserver to Read, Write and Execute files & folders
# While allowing everyone else to only Read or Execute
chmod -R 775 ./storage

Just to reiterate, There's better and more in-depth guide elsewhere, Just have a google, but the above may help you understand what's going on when you're setting permission on your server.

@ssddanbrown commented on GitHub (Jun 9, 2018): Lol, This is the most popular page of all BookStack GitHub pages. Hello fellow Laravel developers who have googled their writable storage issues. It's important to be aware of what permissions you are setting so I thought I'd provide a little overview. Better, more detailed guides are available via more googling. # Unix-Style Permissions Files and folders have 3 main permissions: `read`, `write` & `execute`. Files and folders are also assigned an `owner` and `group`. ## Reading Permissions You can run `ls -alh` in the terminal to show the files and folders with their permissions: ```bash # ls -alh drwxrwxr-x 5 dan dan 4.0K May 28 13:58 . drwxrwxr-x 18 dan dan 4.0K Jun 9 10:38 .. -rw-r--r-- 1 dan dan 5.6K Dec 10 18:19 book_default_cover.png drwxr-xr-x 2 dan dan 4.0K Jun 9 10:40 dist -rw-rwxr-- 1 www-data dan 11K Oct 26 2016 favicon.ico -rw-r--r-- 1 dan dan 412 Aug 9 2017 .htaccess ``` The permissions are on the left, in the first column. The starting `d` is shown if it's a directory. Then there are three sets of `rwx`. * The first set of `rwx` is the permissions for the owner. * The second set of `rwx` is the permissions for the group. * The third set of `rwx` is the permissions for everyone else. Each of these characters represents **r**ead, **w**rite or e**x**ecute. A hyphen (`-`) is shown instead if the permission is not granted. **Note that execute permissions are required on folders to enter them**. The owner assigned to a file/folder can be seen in the third column. The group can be seen in the fourth. In the example above the file `favicon.ico` is assigned to the group `dan` and is owned by `www-data`. The owner `www-data` has permission to read and write the file. The group `dan` has permission to read, write, or execute the file. Everyone else can only read the file. #### Octal Format Permissions may also be shown as numbers in an octal format. In the octal format each permission has a number: * Read = 4 * Write = 2 * Execute = 1 * No permission = 0 These numbers are summed together into a single digit. For example, Having all permissions will be shown as a `7` or only having Read+Execute permissions will be shown as a `5`. These totals are often used in a set of 3 to represent the permissions for the group, owner & everyone else. In the example command output above, the permissions for `favicon.ico` could be shown as `674`. The `.htaccess` file permissions could be shown as `644`. All permissions granted to everyone would show as `777`. ## Setting Permissions There are two main commands for controlling permissions: * `chmod` (Change mode), Used to set permissions. * `chown` (Change ownership), Used to change the owner and group. For both of these commands using `-R` will set permissions recursively upon all child files and directories. #### chmod usage ```shell # Format: chmod [OPTIONS] PERMISSONS FILES... # Example: # Grant the owner and group 'read+write+execute' permissions # Give everyone else 'read and execute' permissions # In the './storage' directory and all files+folders within. chmod -R 775 ./storage ``` #### chown usage ```shell # Format: chown [OPTIONS] USER:GROUP # Example: # In the './storage' directory and all files+folders within # Set the owner to be 'dan' and set the group to be 'www-data' chown -R dan:www-data ./storage ``` #### Common use For things such as file uploads, you'd generally want these to be both readable and writable by the webserver. The user and group your web server runs as will depend on your system and config. On ubuntu it's common for apache and nginx to run as `www-data`, both as the owner and group. In this case, If i wanted to give the webserver permission to upload and serve files within the `./storage` directory I might do the following: ```shell # Recursively set myself as the owner and the web server as the assigned group chown -R dan:www-data ./storage # Recursively allow myself and the webserver to Read, Write and Execute files & folders # While allowing everyone else to only Read or Execute chmod -R 775 ./storage ``` --- Just to reiterate, There's better and more in-depth guide elsewhere, Just have a google, but the above may help you understand what's going on when you're setting permission on your server.
Author
Owner

@lieszkol commented on GitHub (Jul 15, 2018):

I don't remember ever seeing such a nice, concise yet in-depth overview of Unix permissions management on the net anywhere. Funny it's hidden in an obscure post on the BookStack forum. Thanks :-)

@lieszkol commented on GitHub (Jul 15, 2018): I don't remember ever seeing such a nice, concise yet in-depth overview of Unix permissions management on the net anywhere. Funny it's hidden in an obscure post on the BookStack forum. Thanks :-)
Author
Owner

@msamgan commented on GitHub (Jul 27, 2018):

changing the permission of directory works but not a permanent solution.
when the next day a new log is created the same problem is faced again.

any solution to this ?

@msamgan commented on GitHub (Jul 27, 2018): changing the permission of directory works but not a permanent solution. when the next day a new log is created the same problem is faced again. any solution to this ?
Author
Owner

@ssddanbrown commented on GitHub (Jul 28, 2018):

@samgan-khan Review your permissions. Whatever process creates the log files will need write permissions on the parent directory.

@ssddanbrown commented on GitHub (Jul 28, 2018): @samgan-khan Review your permissions. Whatever process creates the log files will need write permissions on the parent directory.
Author
Owner

@luwynne commented on GitHub (Aug 6, 2018):

Can you guys be more straight to the point? How to solve this problem?

@luwynne commented on GitHub (Aug 6, 2018): Can you guys be more straight to the point? How to solve this problem?
Author
Owner

@msamgan commented on GitHub (Aug 6, 2018):

@ssddanbrown I finally got the solution to this problem.
in logging.php->driver->daily add a permission key too with 775 and you are good to go.
it will add the permission to the created file and apache user will also be able to write in it.

@msamgan commented on GitHub (Aug 6, 2018): @ssddanbrown I finally got the solution to this problem. in logging.php->driver->daily add a permission key too with 775 and you are good to go. it will add the permission to the created file and apache user will also be able to write in it.
Author
Owner

@msamgan commented on GitHub (Aug 6, 2018):

@luwynne please follow the above comment and ii guess the problem will be solved.

@msamgan commented on GitHub (Aug 6, 2018): @luwynne please follow the above comment and ii guess the problem will be solved.
Author
Owner

@ssddanbrown commented on GitHub (Aug 6, 2018):

Just to be clear for BookStack users, The solution two comments above does not currently apply.

@samgan-khan Thank you for posting a solution but understand this is not the solution for everyone. Permitted permissions on this file depend on you webserver, existing permissions and how the file was originally created.

@luwynne touch storage/logs/laravel.log && chmod 777 storage/logs/laravel.log will probably solve this for you but is overly permissive. Since you are a developer I'd really encourage you to understand why this is happening (Hence my long post above) and I guarantee it will help in your future development work and overall save you time.

@ssddanbrown commented on GitHub (Aug 6, 2018): Just to be clear for BookStack users, The solution two comments above does not currently apply. @samgan-khan Thank you for posting _a_ solution but understand this is not _the_ solution for everyone. Permitted permissions on this file depend on you webserver, existing permissions and how the file was originally created. @luwynne `touch storage/logs/laravel.log && chmod 777 storage/logs/laravel.log` will probably solve this for you but is overly permissive. Since you are a developer I'd really encourage you to understand why this is happening (Hence my long post above) and I guarantee it will help in your future development work and overall save you time.
Author
Owner

@lommes commented on GitHub (Aug 6, 2018):

@ssddanbrown as far as I know, you made two minor mistakes in your explanation. The first rwx is for the user and the second for the group. Same goes for the chown command (user:group instead of group:user which you correctly used in the last code block).

But basically UNIX permissions is a must for every web developer and one of the most common errors! There is no "golden rule" since there are too many possible scenarios (OS, setup, sticky bits, ...). You need to know some facts about your hosting environment. Hosting panels will often handle user rights differently to basic manually installed webserver, some distributions use different service names (e.g. in CentOS there is no www-data user, apache is used instead, but the service is not called apache, it's httpd there). The better you know your hosting environment, the easier it is for you to track down issues (or for us to help).

Setting wrong permissions (and 777 is a wrong permission in most cases) leads to lowered security. In some cases this might lead to full disclosure of sensitive data (Log may contain mysql user and password if the mysql server is not accessible for a short time and with 777 be exposed to the web, luckily Laravel does not write user and password to the log).

An easy way to find out what user is delivering your site to the browser is to place a simple php file in your webroot and use it to create a file like:

<?php
touch('/tmp/permissionstestfile'); #replace tmp with a directory you know everybody has write access if using tmp is not possible

After calling it once in your browser, with ls -l /tmp you will see user and group the webserver needs for reading/writing files.

@lommes commented on GitHub (Aug 6, 2018): @ssddanbrown as far as I know, you made two minor mistakes in your explanation. The first rwx is for the user and the second for the group. Same goes for the chown command (user:group instead of group:user which you correctly used in the last code block). But basically UNIX permissions is a must for every web developer and one of the most common errors! There is no "golden rule" since there are too many possible scenarios (OS, setup, sticky bits, ...). You need to know some facts about your hosting environment. Hosting panels will often handle user rights differently to basic manually installed webserver, some distributions use different service names (e.g. in CentOS there is no www-data user, apache is used instead, but the service is not called apache, it's httpd there). The better you know your hosting environment, the easier it is for you to track down issues (or for us to help). Setting wrong permissions (and 777 is a wrong permission in most cases) leads to lowered security. In some cases this might lead to full disclosure of sensitive data (Log may contain mysql user and password if the mysql server is not accessible for a short time and with 777 be exposed to the web, **luckily Laravel does not write user and password to the log)**. An easy way to find out what user is delivering your site to the browser is to place a simple php file in your webroot and use it to create a file like: ``` <?php touch('/tmp/permissionstestfile'); #replace tmp with a directory you know everybody has write access if using tmp is not possible ``` After calling it once in your browser, with `ls -l /tmp` you will see user and group the webserver needs for reading/writing files.
Author
Owner

@ssddanbrown commented on GitHub (Aug 6, 2018):

@lommes Thanks for pointing those errors, I always muddle up the ordering in my head, Now updated 👍

Totally agree with all the above. It's an easy thing for developers to skip over and think it's just some sort of odd bug that applying 777 solves but it's not as hard as it first seems to understand. It does benefit developers to have a base understanding of this.

For fellow video learners:
https://www.youtube.com/watch?v=8SkN7UofOww

@ssddanbrown commented on GitHub (Aug 6, 2018): @lommes Thanks for pointing those errors, I always muddle up the ordering in my head, Now updated :+1: Totally agree with all the above. It's an easy thing for developers to skip over and think it's just some sort of odd bug that applying `777` solves but it's not as hard as it first seems to understand. It does benefit developers to have a base understanding of this. For fellow video learners: https://www.youtube.com/watch?v=8SkN7UofOww
Author
Owner

@pascualstromsnes commented on GitHub (Aug 8, 2018):

Another culprit behind this error could also be selinux.

See https://linuxhint.com/how-to-disable-selinux-on-centos-7/

@pascualstromsnes commented on GitHub (Aug 8, 2018): Another culprit behind this error could also be selinux. See **https://linuxhint.com/how-to-disable-selinux-on-centos-7/**
Author
Owner

@hamid-ne commented on GitHub (Mar 22, 2019):

Fixed my problem with this command in centos 7.6 Server

chcon -R -t httpd_sys_content_t $SITE_PATH
 
chcon -R -t httpd_sys_rw_content_t $SITE_PATH
@hamid-ne commented on GitHub (Mar 22, 2019): Fixed my problem with this command in centos 7.6 Server ``` chcon -R -t httpd_sys_content_t $SITE_PATH chcon -R -t httpd_sys_rw_content_t $SITE_PATH ```
Author
Owner

@ssddanbrown commented on GitHub (Jun 24, 2019):

@vikasrinvi That is a subtly different issue. This has been answered above already.

@ssddanbrown commented on GitHub (Jun 24, 2019): @vikasrinvi That is a subtly different issue. This has been answered above already.
Author
Owner

@ormanfaghihi commented on GitHub (Jul 23, 2019):

chmod -R 775 storage also worked for me 😍😍😍😍😍

@ormanfaghihi commented on GitHub (Jul 23, 2019): `chmod -R 775 storage` also worked for me 😍😍😍😍😍
Author
Owner

@ssddanbrown commented on GitHub (Aug 3, 2019):

I'm going to lock this off as further comments will only really mis-guide people.

To Laravel Developers

Learn how permissions work and how to apply them correctly instead of blindly running permission commands. It will be beneficial.

To BookStack users

If you're having trouble understanding any of the above please open a new issue so that we can troubleshoot your particular scenario.

@ssddanbrown commented on GitHub (Aug 3, 2019): I'm going to lock this off as further comments will only really mis-guide people. # To Laravel Developers [Learn how permissions work and how to apply them correctly](https://github.com/BookStackApp/BookStack/issues/436#issuecomment-395964366) instead of blindly running permission commands. It will be beneficial. # To BookStack users If you're having trouble understanding any of the above please open a new issue so that we can troubleshoot your particular scenario.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#370