php - 如何使用 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 写权限到挂载的卷?
解决方案
我在@Nguyen 的指导下找到了一个解决方案,尽管在我的情况下还有更多问题,所以我想我会写下我自己的详细答案,以防它可能对某人有所帮助。
如果你在 MacOS 上使用 Docker,Docker 实际上是在 Linux VM 上运行,而不是在机器上本机运行。在尝试更改主机上的权限时,这让我感到很困惑(从 docker 的角度来看,主机是虚拟机)。
我使用以下函数找到了执行我的 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 具有完全权限的容器中。然后,您可以像往常一样更改保存卷的目录的权限。
推荐阅读
- android - android - fontFamily 无法在 androidx 上运行
- ios - iOS Swift:从 iOS 框架向 iOS 应用发送日志信息
- mysql - 创建将 4 个元组汇总为一个的 VIEW
- r - R:由于内存问题,dplyr 不能与 spark 一起使用
- batch-file - 为什么此脚本在不同帐户上的运行方式不同?
- python - 在 GeoDjango 中将多边形层与多边形相交
- javascript - Javascript 正则表达式字符串
- html - 图片标签使用 data-srcset 代替 srcset
- excel - 如何使用 VBA 将值和格式复制并粘贴到新工作表
- javascript - Vue js + Laravel 6,路由器视图不渲染组件