【问题标题】:Docker Laravel - could not be opened in append mode: failed to open stream: Permission deniedDocker Laravel - 无法以附加模式打开:无法打开流:权限被拒绝
【发布时间】:2021-07-18 23:28:33
【问题描述】:

几乎一整天都在尝试修复此错误,但不知道可能导致此问题的原因。

我得到的错误是:UnexpectedValueException 无法以附加模式打开流或文件“/var/www/storage/logs/laravel.log”:无法打开流:权限被拒绝

以下是我的 docker-compose.yml、Dockerfile 和 conf.d 文件。

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;
    }
}

我尝试了很多解决方案,但都没有奏效。

谢谢。

【问题讨论】:

  • 安装 Laravel Sail

标签: laravel docker


【解决方案1】:

您需要确保 docker 容器内的用户与拥有主机上文件的用户使用相同的 uid 和 gid 运行。

您可以使用检查容器用户权限

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

在您的示例中,路径是 /var/www/

然后检查主机中的用户权限

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

在您的示例中,路径是 ./

要对其进行测试,您只需将Dockerfile 中的uid 和gid 更改为与主机上的用户相同,它应该可以工作。 为了能够通过您的docker-compose.yml 传递这些数据,您可以将build-args 添加到您的撰写文件中,例如Documentation。

您还可以查看Laravel Sail 的做法。

【讨论】:

    【解决方案2】:

    你的问题的答案确实很简单。

    首先,请记住 docker 默认以 root 身份运行,因此在创建容器期间执行的所有操作均由 root 用户完成。

    发生的情况是您在切换到新创建的 www 用户后运行命令 COPY --chown=www-data:www-data . /var/www:此用户无权更改 root 拥有的文件夹的所有者!

    另一个错误是您要设置文件夹所有权的用户不是 www-data 而是您刚刚创建的 www 用户。

    你最终想要的是切换2个命令的顺序并将用户从www-data更改为www,如下所示:

    改变这个

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

    进入这个

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

    【讨论】:

      【解决方案3】:

      试试这个:

      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
      

      登录容器终端,查看目录和文件权限

      >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
      

      另外,php-fpm 必须由www-data 用户执行。

      >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 
      

      如果不是这种情况,则使用 www-data.conf 文件覆盖 /etc/php/7.3/fpm/pool.d 目录(复制或挂载为卷)

      [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
      

      【讨论】:

      • 尝试构建映像时出现此错误:> [8/11] RUN addgroup -g 1000 -S www-data && adduser -u 1000 -S www-data -G www-data : #12 0.302 addgroup: group 'www-data' in use
      • 您似乎已经拥有www-data 用户。我稍微纠正了我的答案,现在我们创建了一个用户www,也许你仍然需要他(如果没有,请完全删除)并且我们设置权限 www (user)::www-data (group),这应该可以。跨度>
      • 它运行了,但我仍然遇到同样的错误,无法访问 laravel.log
      • 你能显示ls -al /var/www/、ls -al /var/www/storage/logs、top的输出吗?
      猜你喜欢
      • 2022-07-07
      • 2021-10-01
      • 2021-10-03
      • 2021-10-03
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-29
      • 2020-11-21
      相关资源
      最近更新 更多