ltdev
ltdev

Reputation: 4477

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

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?

Upvotes: 53

Views: 162056

Answers (10)

Run bellow command from host machine

chown -R www-data:www-data /var/www/html chmod -R 777 /var/www/html/storage

Upvotes: 1

Vit
Vit

Reputation: 488

Had that issue on Win10. I have moved L10 files to \\wsl.localhost\Ubuntu-22.04\home\user1\projects and when opened http://localhost:8000/ got same error.

Check permissions by running WSL terminal in VScode: docker container exec -it cnphp ls -la - See that all folders and files are owned by xfs, except storage. Actually storage was owned by xfs but here how I solved it:

1- name your app or php container in docker-compose.yml file container_name: cnphp

2- run in VScode in WSL-terminal:docker-compose up -d and

docker container exec -it cnphp  chown -R www-data:www-data /var/www/laravel/bootstrap/cache
docker container exec -it cnphp  chown -R www-data:www-data /var/www/laravel/storage/logs/laravel.log

After docker-compose down and docker-compose up owner remains www-data and error gone.

After this manipulations if you will run WSL itself, you will see enter image description here I can not comment this, but you see that that WSL shows that storage owner is set to "82" and in VScode storage is "www-data". So the conclusion - use WSL-Ubuntu terminal in VScode to set correct owner.

Upvotes: 1

Developer Jay
Developer Jay

Reputation: 1373

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.

You should also give access to the www-data user or group.

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

Upvotes: 104

Promise Preston
Promise Preston

Reputation: 28940

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

Upvotes: 1

Nam Sama
Nam Sama

Reputation: 455

  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/

Upvotes: 13

Mangesh Sathe
Mangesh Sathe

Reputation: 2177

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

Upvotes: 5

Rob Mascaro
Rob Mascaro

Reputation: 851

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

Upvotes: 26

david russell
david russell

Reputation: 1

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

Upvotes: -2

Milos Jankovic
Milos Jankovic

Reputation: 506

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

WWWGROUP=1000
WWWUSER=1000

Upvotes: 31

Tooschee
Tooschee

Reputation: 741

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]

Upvotes: 49

Related Questions