繁体   English   中英

如何使用 PHP、docker-compose 将用户上传的文件保存到挂载卷?

[英]How to save user uploaded files to mounted volume using PHP, docker-compose?

我有一个使用 docker-compose 配置的 LAMP 堆栈,并且在将用户上传的文件保存到已安装的卷以进行持久存储时遇到问题。 这是我的撰写文件:

    version: '3.7'
services:

  php-apache:
    build: './php-apache'
    restart: always
    ports:
      - 5000:80
    volumes:
      - ./public_html:/var/www/html
      - ./composer/vendor:/var/www/html/vendor
      - ./tmp:/usr/local/tmp
      - ./cert/:/usr/local/apache2/cert
      - covers:/var/lib/app-data/covers:rw
      - ebooks:/var/lib/app-data/ebooks:rw
    depends_on: 
      - mysql
      - composer

  mysql:
    build: './mysql'
    restart: always
    ports:
      - '33061:3306'
    volumes:
      - ./database:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    environment: 
      MYSQL_ROOT_PASSWORD: secretpw
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypw 
      MYSQL_DATABASE: mydb

  composer:
    build: './composer'
    working_dir: /composer
    volumes:
      - ./composer:/composer
    command: install

volumes:
  covers: {}
  ebooks: {}

在我的 PHP 代码中,我尝试将文件保存到卷中:

    if (!move_uploaded_file($_FILES[$file]['tmp_name'], $path . $filename)) {
        throw new RuntimeException("Failed to move uploaded file.");
    }

我收到以下错误:

警告:move_uploaded_file(/var/lib/app-data/covers/useruploadedfile.jpg):无法打开流:权限被拒绝

我试图更改卷的权限无济于事。 有什么方法可以给 PHP 对挂载卷的写权限?

我试图更改卷的权限无济于事。 有什么方法可以给 PHP 对挂载卷的写权限?

简而言之,在您的场景中,无法从 docker 容器内更改已安装卷的权限。 您需要从主机级别执行此操作。

当主机基于 Linux(例如 RedHat、Ubuntu)时,通常会发生此问题,而它在 MacOS 上可以正常工作。 您将需要:

  • 找出 docker 容器内的哪个用户 ID 正在运行该命令。
  • 确保主机上的相同用户 ID 有足够的权限在挂载的文件夹中创建文件。

我在@Nguyen 的指导下找到了一个解决方案,尽管在我的情况下还有更多问题,所以我想我会写下自己的详细答案,以防万一它可能对某人有所帮助。

如果你在 MacOS 上使用 Docker,Docker 实际上是在 Linux VM 上运行,而不是在机器上运行。 这让我在尝试更改主机上的权限时绊倒了(从 docker 的角度来看,主机是 VM)。

我使用以下函数找到了正在执行我的 PHP 脚本的用户和组 ID:

echo posix_getuid();
echo posix_getgid();

我使用以下命令找到了我的卷的安装位置:

docker volume inspect nameofyourvolume

当我尝试 chown 卷安装在 (/var/lib/docker/volumes) 中的目录时,我得到“没有这样的文件或目录”。 经过一番研究,我意识到挂载位置的路径是相对于运行 docker 的 VM 而言的。 我找到了一种使用以下命令进入此 VM 的方法(请参阅https://www.bretfisher.com/docker-for-mac-commands-for-getting-into-local-docker-vm/ ):

docker run -it --rm --privileged --pid=host justincormack/nsenter1

这会将您带入一个对 VM 具有完全权限的容器中。 然后,您可以像往常一样更改保存卷的目录的权限。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM