【问题标题】:Permission Denied Error using Laravel & Docker使用 Laravel 和 Docker 的权限被拒绝错误
【发布时间】:2018-07-15 02:59:37
【问题描述】:

我有两个 docker 容器:Nginx 和 App。
应用容器扩展了 PHP-fpm 并且还有我的 Laravel 代码。

在我的docker-compose.yml 我正在做:

version: '2'
services:
    nginx:
        build:
            context: ./nginx
            dockerfile: ./Dockerfile
        ports:
            - "80:80"
        links:
            - app
    app:
        build:
            context: ./app
            dockerfile: ./Dockerfile

在我正在做的 Nginx Dockerfile 中:

FROM nginx:latest
WORKDIR /var/www
ADD ./nginx.conf /etc/nginx/conf.d/default.conf
ADD . /var/www
EXPOSE 80

在我正在做的应用程序 Dockerfile 中:

FROM php:7-fpm
WORKDIR /var/www
RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client && docker-php-ext-install mcrypt pdo_mysql
ADD . /var/www

成功运行docker-compose up后,尝试localhost时出现如下错误

无法打开流或文件“/var/www/storage/logs/laravel.log”:无法打开流:权限被拒绝

据我了解,存储文件夹需要网络服务器可写。
我应该怎么做才能解决这个问题?

【问题讨论】:

    标签: php laravel docker nginx docker-compose


    【解决方案1】:

    使您的 Dockerfile 如下所示 -

    FROM php:7-fpm
    WORKDIR /var/www
    RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client && docker-php-ext-install mcrypt pdo_mysql
    ADD . /var/www
    RUN chown -R www-data:www-data /var/www
    

    这使得目录/var/wwwwww-data 所有,这是php-fpm 的默认用户。

    因为它是用用户www-data编译的。

    参考-

    https://github.com/docker-library/php/blob/57b41cfc2d1e07acab2e60d59a0cb19d83056fc1/7.0/jessie/fpm/Dockerfile

    【讨论】:

    • 这对我不起作用。同样的错误。任何人都有任何想法。
    • 我也遇到了同样的问题。这个解决方案对我也不起作用。
    • 您可以在ADDCOPY 指令上使用--chown 标志来减小图像大小。喜欢COPY --chown=www-data:www-data . /var/www。在我的例子中,图像的大小从 130MB 减少到了 100MB。
    • 对我来说,我不得不使用这个命令 docker exec -i -t (here is you container id) bash 深入容器本身
    • 找到一篇文章解释了这背后的原因。我的问题 - 我使用的是 Linux - github.com/shipping-docker/vessel-docs/blob/master/source/docs/…
    【解决方案2】:

    我发现了类似的问题,并通过

    修复了它
    chown -R www-data:www-data /var/www
    
    chmod -R 755 /var/www/storage
    

    【讨论】:

    • 我得到:“无法访问'/var/www/storage':没有这样的文件或目录”
    【解决方案3】:

    在 Docker 中使用绑定挂载时,Docker 主机中的原始权限会保留在容器中。这使我们能够在 Docker 主机上设置适当的权限,以便在容器内使用。

    首先,你应该找到nginx的uidgid,例如:

    docker-compose exec nginx id www-data

    这个命令的输出是这样的:

    uid=33(www-data) gid=33(www-data) groups=33(www-data)

    然后,您应该使用这些uidgid 来设置Docker 主机上的权限,容器也将使用这些权限。因此,在 Docker 主机上运行以下命令:

    sudo chown -R 33:33 site

    现在一切都必须正常工作。

    【讨论】:

    • 谢谢!顺便说一句,当您使用COPY --chown=33:33 . . 复制数据时,您可以在 Dockerfile 中轻松执行此操作。这保留了原始文件的所有权。 (不过,我听说这在 Windows 上不起作用。)
    • 也许是 docker exec 而不是 docker-compose exec?
    【解决方案4】:

    您可以按照我使用/使用的方式做 3 件事

    1. 授予storage文件夹的755权限(sudo chmod 755 storage/ storage/*

    2. RUN chown -R www-data:www-data /var/www RUN chmod 755 /var/www

    3. 将项目文件夹移动到/home,无需特殊权限即可在该目录上写入(个人推荐此)(在我的我使用/home/projects/,所有这些都放在那里) .


    注意:如果项目位于/var/www/,那么如果您编写了文件上传,您也需要对该文件夹的权限。当您将其移至 /home 时,这将避免此类错误

    【讨论】:

    • 只是一个想法,但 777 是 Web 服务器文件夹的不安全权限设置。一个建议是改用“ug+rw”之类的东西(为 USER(所有者)和 GROUP 添加 READ 和 WRITE)。
    • @SamuelBié 啊刚刚看到这些评论。错字755
    【解决方案5】:

    我尝试了所有这些,但都没有奏效。我的 Laravel 存储文件夹可以访问。但是/var/www/storage还是没有权限。

    在阅读了多个建议后,尤其是this。我做了以下操作(请注意 php 是我的容器镜像的名称,我将我的 laravel 项目直接链接到 /var/www):

    1. 从我的码头,我跑了docker-compose exec php ls -al /var/www/storage
      • 我看到只有 root 可以访问,但我需要 www-data 才能访问。
    2. 然后我跑了docker-compose exec php chown -R $USER:www-data /var/www/storage
      • 这使www-data 可以访问存储文件夹
    3. 然后我跑了docker-compose exec php chown -R $USER:www-data /var/www/bootstrap/cache
      • 这使 www-data 可以访问 bootstrap/cache 文件夹

    如果你再次运行第 1 项,www-data 应该可以访问,你的 Laravel 应用应该没问题。

    【讨论】:

      【解决方案6】:

      您需要创建一个与您机器上的用户(您创建项目文件时使用的用户)匹配的用户。所以在应用程序 Dockerfile 中,像这样更改你的文件:

      FROM php:fpm
      
      # Arguments defined in docker-compose.yml
      ARG user
      ARG uid
      
      # Install system dependencies
      RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client
      
      # Install PHP extensions
      RUN docker-php-ext-install mcrypt pdo_mysql
      
      # Get latest Composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      
      # Create system user to run Composer and Artisan Commands
      RUN useradd -G www-data,root -u $uid -d /home/$user $user
      RUN mkdir -p /home/$user/.composer && \
          chown -R $user:$user /home/$user
      
      # Set working directory
      WORKDIR /var/www
      
      # Set the user
      USER $user
      
      # Copy your files
      COPY . . # You can use "." as a destination since you already changed the workdir
      

      快速说明:如果您将 docker 纯粹用于本地开发,则无需复制任何内容,只需使用绑定挂载即可。

      在您的 docker-compose 文件中,进行以下更改:

      app:
          build:
              args:
                  user: essana3 # your username on your machine, you can get it by running echo $USER
                  uid: 1000 # your uid which you can get by running id -u
              context: ./app
              dockerfile: Dockerfile # if your dockerfile is called Dockerfile, you don't need to add the dockerfile option
          volumes:
              - ./app:/var/www
      

      奖励: 您可以使用上面的 dockerfile 在 docker-compose 文件中创建实用程序容器来运行 artisan 和 composer 命令:

        composer:
          build:
            args:
              user: essana3 # your username (echo $USER)
              uid: 1000 # your uid (id -u)
            context: ./app
          working_dir: /var/www
          volumes:
            - ./app:/var/www
          entrypoint: ['composer']
      
        artisan:
          build:
            args:
              user: essana3 # your username (echo $USER)
              uid: 1000 # your uid (id -u)
            context: ./app
          working_dir: /var/www
          volumes:
            - ./app:/var/www
          entrypoint: ['php', 'artisan']
      

      【讨论】:

        【解决方案7】:

        从 Laravel 8 开始,强烈建议您使用 Laravel Sail 来管理具有多个容器的 Laravel 应用程序。 Sail 无缝处理有关容器用户、组和权限的所有内容,并允许多个 docker 容器自动通信。

        对于现有应用程序,首先备份您的 docker-composer.yml 文件,然后通过 composer 请求 Sail

        composer require laravel/sail --dev
        

        然后使用安装

        php artisan sail:install
        

        在应用程序的根文件夹中,您会找到 Sail 自己的 docker-composer.yml 文件。与您的备份版本进行比较,并在必要时进行更改。

        最后,通过运行调出所有相关容器

        ./vendor/bin/sail up
        

        查看 Laravel Sail 的 documentation 了解更多详情。

        【讨论】:

          【解决方案8】:

          你可以右键单击你的 laravel 文件夹,单击属性,然后单击权限,然后从“组”字段中,选择“docker”并为“docker”组提供必要的权限:) 这对我有用

          【讨论】:

          • 这里 Docker 在上下文中。一切都使用终端而不是 GUI 控制
          猜你喜欢
          • 1970-01-01
          • 2016-10-18
          • 1970-01-01
          • 2018-12-15
          • 1970-01-01
          • 1970-01-01
          • 2023-03-22
          • 1970-01-01
          • 2016-05-03
          相关资源
          最近更新 更多