skip to Main Content

Have been trying to fix this error for almost an entire day now and have no idea what is possibly causing this issue.

The error I get is: UnexpectedValueException
The stream or file "/var/www/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission denied

Below are my docker-compose.yml, Dockerfile and conf.d files.

docker-compose.yml:

version: "3"
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: /laravelproject
    container_name: app
    restart: unless-stopped
    volumes:
      - ./:/var/www
      - ./config/php/local.ini:/usr/local/etc/php/conf.d/local.ini

  webserver:
    build:
      context: .
      dockerfile: Dockerfile_Nginx
    image: /nginx
    container_name: webserver
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./:/var/www
      - ./config/nginx/conf.d/:/etc/nginx/conf.d/
    depends_on:
      - app

Dockerfile:

FROM php:7.3-fpm-alpine

WORKDIR /var/www

RUN apk update && apk add 
    build-base 
    freetype-dev 
    libjpeg-turbo-dev 
    libpng-dev 
    libzip-dev 
    zip 
    jpegoptim optipng pngquant gifsicle 
    vim 
    unzip 
    git 
    curl

RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd

# copy config
COPY ./config/php/local.ini /usr/local/etc/php/conf.d/local.ini

RUN addgroup -g 1000 -S www && 
    adduser -u 1000 -S www -G www

USER www

COPY --chown=www-data:www-data . /var/www

EXPOSE 9000

app.conf:

server{
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    location ~ .php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

I have tried many solutions but none of them have worked.

Thanks.

4

Answers


  1. Try this:

    FROM php:7.3-fpm-alpine
    
    WORKDIR /var/www
    
    RUN apk update && apk add 
        build-base 
        freetype-dev 
        libjpeg-turbo-dev 
        libpng-dev 
        libzip-dev 
        zip 
        jpegoptim optipng pngquant gifsicle 
        vim 
        unzip 
        git 
        curl
    
    RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
    RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
    RUN docker-php-ext-install gd
    
    # copy config
    COPY ./config/php/local.ini /usr/local/etc/php/conf.d/local.ini
    
    RUN addgroup -g 1000 -S www && 
        adduser -u 1000 -S www -G www
    
    #USER root
    
    COPY --chown=www:www-data . /var/www
    
    RUN chown -R www:www-data /var/www/storage
    RUN chmod -R ug+w /var/www/storage
    
    EXPOSE 9000
    

    Login to the container terminal and check the directory and file permissions

    >ls -al
    
    drw-r--r-- 1 www www-data      0 Apr 25 11:57 storage
    -rwxrw-rw- 1 www www-data 34434 Apr 25 12:45 laravel.log
    

    Also, php-fpm must be executed by www-data user.

    >top
    
    17 root      20   0  236968   8232   2140 S   0.0   0.0   0:00.00 php-fpm7.3 
    18 www-data  20   0  236968   8264   2164 S   0.0   0.0   0:00.00 php-fpm7.3 
    19 www-data  20   0  236968   8264   2164 S   0.0   0.0   0:00.00 php-fpm7.3 
    

    If this isn’t the case then override the /etc/php/7.3/fpm/pool.d directory with www-data.conf file (copy or mount as a volume)

    [www-data.conf]
    
    user = www-data
    group = www-data
    
    listen = /run/php/php7.3-fpm.sock
    
    listen.owner = www-data
    listen.group = www-data
    
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    
    Login or Signup to reply.
  2. You need to make sure the user inside the docker container is running with the same uid and gid as the user that owns the files on your host.

    You can inspect the container user privileges using

    docker-compose exec <service-name> ls -la /path/to/app/directory
    

    in your example the path is /var/www/

    and then inspect the user privileges int the host

    ls -la /path/to/host/mount/point
    

    in your example the path is ./

    To test it you can just change the uid and gid in your Dockerfile to be the same as your user on the host and it should work.
    To be able to pass in this data through your docker-compose.yml you can add build-args to your compose file like int the Documentation.

    You can also review the way that Laravel Sail does it.

    Login or Signup to reply.
  3. The answer to your question is pretty easy indeed.

    First of all, remember that docker runs as root by default so all the actions taken during the creation of your container are done by the root user.

    What is happening is that you are running the command COPY --chown=www-data:www-data . /var/www after having switched to the newly created www user: this user does not have the rights to change the owner of a folder own by root!

    Another error is that the user you want to set the folder ownership to is not www-data but the www user you just created.

    What you want, in the end, is to switch the order of the 2 commands and change the user from www-data to www, look below:

    CHANGE THIS

    USER www
    
    COPY --chown=www-data:www-data . /var/www
    

    INTO THIS

    COPY --chown=www:www . /var/www
    
    USER www
    
    Login or Signup to reply.
  4. I ran into this problem using Docker Desktop with Laravel on Windows 10. I was running into file permission issues. Namely: file_put_contents(...): failed to open stream: No such file or directory.

    Editing the permissions would allow me to use artisan commands to create files, but then prevent me from actually editing the files locally using Visual Studio Code (or vice versa).

    A lot of searching didn’t yield helpful results until I found this post about the issue: https://github.com/laravel/sail/issues/81#issuecomment-1304499939

    The issue could be replicated by starting the container using the GUI play button in docker desktop.

    The issue can be avoided by starting your container from command line with:

        sail up -d
    

    The -d flag is optional (to run it in the background). After starting this way via command line (instead of using the Docker Desktop client play button) – the permission issues go away. The primary difference I can find is that if the container is spun up using Docker Desktop, inside the container the

    Group:User == 1000:sail.

    If the command sail up -d is used, inside the container the

    Group:User == sail:sail.

    You can confirm yourself by starting using both methods, and running sail root-shell, then once in the container ls -ll.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search