36

This is my folder structure:

+-- root-app-dir
|   +-- docker
|   |   +-- Dockerfile
|   |   +-- nginx.conf
|   +-- src // this is where the Laravel app lives
|   +-- docker-compose.yml

This is my docker-compose.yml

version: '2'

services:
  app:
    build:
      context: ./docker
      dockerfile: Dockerfile
    image: lykos/laravel
    volumes:
      - ./src/:/var/www/html/
    networks:
      - app-network

  nginx:
    image: nginx:latest
    volumes:
      - ./src/:/var/www/html/
      - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf
    ports:
      - 8000:80
    networks:
      - app-network

  mysql:
    image: mysql:5.7
    ports: 
      - "4306:3306"
    environment:
      MYSQL_DATABASE: homestead
      MYSQL_USER: homestead
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - mysqldata:/var/lib/mysql
    networks:
      - app-network

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - 8080:80
    links:
      - mysql
    environment:
      PMA_HOST: mysql

volumes:
  mysqldata:
    driver: "local"

networks:
  app-network:
    driver: "bridge"

This is my nginx.conf

server {
  root /var/www/html/public;

  index index.html index.htm index.php;

  server_name _;
  charset utf-8;

  location = /favicon.ico { log_not_found off; access_log off; }
  location = /robots.txt { log_not_found off; access_log off; }

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ \.php$ {
    # include snippets/fastcgi-php.conf;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass app:9000;
    fastcgi_index index.php;
  }

  error_page 404 /index.php;

  location ~ /\.ht {
    deny all;
  }
}

When I run docker-compose up -d and try to access the Laravel app through the htts://localhost:8000 I get this error on my screen

UnexpectedValueException
The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied

I have run sudo chown lykos:lykos -R ./src from my root-app-dir but the issue is still there. How can I fix this?

ltdev
  • 4,037
  • 20
  • 69
  • 129

8 Answers8

63

if the above does not work when its added to your .env file the following will:

sudo chmod o+w ./storage/ -R

this will give others permissions without altering user and group permissions.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Developer Jay
  • 953
  • 1
  • 10
  • 15
  • 9
    This is just a disingenuous way of using `chmod 777`. It's very dangerous, and allows **anyone** to alter the files served to end users. – miken32 Jan 10 '22 at 16:51
  • @miken32 you probably shouldn't use sail as a production env... – Meki Mar 06 '23 at 07:39
  • the file cannot be modified if its served to an end user as these things are controlled via htaccess files or even configuration so that only access point they'd have is through a public directory. – Developer Jay Jun 17 '23 at 00:03
43

There are several options, what could be wrong:

  1. The storage link isn't properly set, you can read about it here, after launching app container, you should do php artisan storage:link to check whether proper link is there
  2. You don't have the proper right for the given folder, from default, logs folder should have www-data writable rights, you can check that by ssh to machine and the do ls -l on files in /var/www/html/[your laravel app], if not, add the proper rights by: chown -R www-data:www-data *
  3. Also related to file permissions: you can disable SELinux (but only in dev server, never do it on live) by cehcking the status: sestatus and then enforcing it to 0 by setenforce 0 (however on live server, it's better to leave SElinux running and try to disable the problem by chcon -R -t httpd_sys_rw_content_t [path to storage folder here]
Caleb
  • 124,013
  • 19
  • 183
  • 272
Tooschee
  • 681
  • 6
  • 11
  • 1
    I am having "chcon: can't apply partial context to unlabeled file" when I do chcon -R -t httpd_sys_rw_content_t – Utku Dalmaz Nov 02 '20 at 06:36
  • 3
    Note that the container would create `/var/www/html/storage/logs/laravel.log` by `root:root` hence you should run `chown -R www-data:www-data .` on root of the project. Next, the PHP would append logs to the mentioned file obviously by `www-data:www-data`. – M. Rostami Nov 08 '20 at 14:21
  • @M.Rostami, can you provide a link to where or how you get this info please, I mean PHP using user: group – dellos Jun 30 '23 at 07:58
  • @dellos PHP processes are usually executed by the web server using a specific user & group. The user & group used by PHP to execute scripts can be determined by checking the server's configuration files. For example, in Apache, the user & group are often set in the `httpd.conf` or `apache2.conf` file, while in Nginx, they are specified in the `nginx.conf` file or so. When PHP creates or modifies files (such as log files), it uses the permissions of the user & group under which it is running. In the case of Laravel, the log files are typically stored in the `storage/logs`. (GPT) – M. Rostami Jun 30 '23 at 08:29
25

If you're using Sail on Docker Windows Desktop with WSL2 this issue arises when you start the docker container directly from the dashboard. Instead, start the container within your WSL2 terminal instance i.e

sail up -d
Rob Mascaro
  • 791
  • 7
  • 16
24

if you are using laravel sail, add following to your .env file

WWWGROUP=1000
WWWUSER=1000
Milos Jankovic
  • 426
  • 4
  • 9
10
  1. With user root:root . You try with command :

    sudo chmod -R 777 storage/

  2. With user www-data:www-data . You try with command :

    sudo chown -R www-data:www-data storage/

    sudo chmod -R 755 storage/

  3. If you use Docker . You try with command :

    sudo chown -R nginx:nginx storage/

    sudo chmod -R 755 storage/

Nam Sama
  • 375
  • 3
  • 6
3

Following worked for me, executed both commands in following sequence in WSL2 command line, Hope this case helps someone

1 : Answer given by @nam-sama

With user root:root . You try with command :

sudo chmod -R 777 storage/

And 2 : Answer given by @Rob-Mascaro

sail up -d
Mangesh Sathe
  • 1,987
  • 4
  • 21
  • 40
1

Just to emphasize more on Toosche's answer. I experienced this issue when trying to deploy a Docker PHP application.

My working directory was /var/www/html. And I added commands to create a USER called docker in the Dockerfile.

And I already had the following commands in my Dockerfile:

RUN sudo chown -R www-data:www-data /var/www/html \
    && sudo chmod 775 -R /var/www/html \

And the below commands in my startup script:

chmod -R ugo+rw /.composer
chown -R $USER:www-data /var/www/html/storage/
chown -R $USER:www-data /var/www/html/bootstrap/cache/
chmod -R 775 /var/www/html/storage/
chmod -R 775 /var/www/html/bootstrap/cache/

After the deployment I get the error below when I try to use the app:

The stream or file "/var/www/html/storage/logs/laravel-2023-02-01.log" could not be opened in append mode: Failed to open stream: Permission denied\nThe exception occurred while attempting to log: The stream or file "/var/www/html/storage/logs/laravel-2023-02-01.log\

Here's how I solved it:

The container creates /var/www/html/storage/logs/laravel.log by root:root after it starts up. So I checked the files and folders ownership in the running container and found the below:

-rw-r--r-- 1 www-data www-data    515 Feb  2 00:09 README.md
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 app
-rwxr-xr-x 1 www-data www-data   1686 Feb  2 00:09 artisan
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 bootstrap
-rw-r--r-- 1 www-data www-data   2098 Feb  2 00:09 composer.json
-rw-r--r-- 1 www-data www-data 312509 Feb  2 00:09 composer.lock
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 config
-rw-r--r-- 1 www-data www-data 726014 Feb  2 00:09 package-lock.json
-rw-r--r-- 1 www-data www-data    473 Feb  2 00:09 package.json
-rw-r--r-- 1 www-data www-data   1202 Feb  2 00:09 phpunit.xml
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 public
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 resources
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 routes
-rw-r--r-- 1 www-data www-data    563 Feb  2 00:09 server.php
drwxr-xr-x 1 root     root       4096 Feb  2 00:09 storage
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 tests
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 vendor
-rw-r--r-- 1 www-data www-data    559 Feb  2 00:09 webpack.mix.js

All I had to do to resolve this and remove duplicated commands was to remove the commands above in my Dockerfile and startup script, and added only the command below in startup script, which gave the www-data user and group permission of all files and folders in the working directory:

chown -R www-data:www-data *

I also left the command below in my startup script for composer:

chmod -R ugo+rw /.composer

Afterwhich I built and redeployed the app again. This time I checked the files and folders ownership in the running container and they were fine as below:

-rw-r--r-- 1 www-data www-data    515 Feb  2 00:09 README.md
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 app
-rwxr-xr-x 1 www-data www-data   1686 Feb  2 00:09 artisan
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 bootstrap
-rw-r--r-- 1 www-data www-data   2098 Feb  2 00:09 composer.json
-rw-r--r-- 1 www-data www-data 312509 Feb  2 00:09 composer.lock
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 config
-rw-r--r-- 1 www-data www-data 726014 Feb  2 00:09 package-lock.json
-rw-r--r-- 1 www-data www-data    473 Feb  2 00:09 package.json
-rw-r--r-- 1 www-data www-data   1202 Feb  2 00:09 phpunit.xml
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 public
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 resources
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 routes
-rw-r--r-- 1 www-data www-data    563 Feb  2 00:09 server.php
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 storage
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 tests
drwxr-xr-x 1 www-data www-data   4096 Feb  2 00:09 vendor
-rw-r--r-- 1 www-data www-data    559 Feb  2 00:09 webpack.mix.js
Promise Preston
  • 24,334
  • 12
  • 145
  • 143
-2

I had this issue because I was using sail and the default directory for the logs thinks I am using Apache. I could not find any way of changing the log location to the correct storage folder, so I created a symbolic link instead:

ln -s /var/www/html/public/storage /home/<yourfoldername>/storage

When I ran my script again, it errored properly, and wrote to laravel.log file in the correct location

Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73