Docker应用能否跨卷复制文件?配置执行后目标目录为空求助
Docker卷间文件复制问题:Silverstripe Vendor资源复制失败
问题背景
我有一个Docker化的Silverstripe应用,用Composer容器下载依赖,通过Silverstripe的vendor-plugin(对应CopyMethod.php第47行的复制逻辑)把vendor目录里的文件复制到public/_resources目录。存储规划如下:
- vendor目录挂载在
ss-vendorDocker卷 - public目录下其他文件挂载到宿主机
./public目录
我试过两种方案:从Docker卷复制到另一个Docker卷、直接复制到宿主机,但都没成功。用当前docker-compose.yml配置后,public/_resources/vendor是空目录,Composer容器日志也没报错。
当前docker-compose.yml配置
services: php: image: silverstripe-php:8.1 build: dockerfile: dockerfiles/php.dockerfile hostname: localhost volumes: - ./public:/var/www/html/public - ss-vendor-resources:/var/www/html/public/_resources/vendor - ./themes:/var/www/html/themes:cached - ss-vendor:/var/www/html/vendor - ./composer.json:/var/www/html/composer.json composer: image: composer/composer volumes: - ./public:/var/www/html/public:cached - ss-vendor:/var/www/html/vendor - ss-vendor-resources:/var/www/html/public/_resources/vendor - ./composer.json:/var/www/html/composer.json working_dir: /var/www/html command: update environment: SS_VENDOR_METHOD: copy volumes: ss-vendor: ss-vendor-resources:
问题分析
- 挂载层级冲突:同时挂载宿主机
./public和ss-vendor-resources卷到/var/www/html/public/_resources/vendor,Docker的挂载是覆盖式的,子目录的卷挂载会覆盖宿主机对应路径,可能导致CopyMethod无法正确写入目标目录。 - 权限不匹配:Docker卷默认由root用户所有,而Composer容器默认以
composer用户运行,可能没有写入目标目录的权限,这种无权限操作通常不会在日志中显式报错。 - 路径匹配问题:需确认CopyMethod中的目标路径是否和容器内
/var/www/html/public/_resources/vendor完全一致,是否存在配置变量未正确传递的情况。
解决方案
1. 调整挂载结构,避免层级冲突
不要同时挂载宿主机目录和卷到其子目录,改为直接绑定挂载目标目录到宿主机,提前在宿主机创建目录并设置权限:
# 宿主机执行 mkdir -p public/_resources/vendor chmod 777 public/_resources/vendor # 测试用,生产环境需设置正确用户权限
修改docker-compose.yml中Composer服务的挂载部分:
volumes: - ./public:/var/www/html/public:cached - ss-vendor:/var/www/html/vendor - ./public/_resources/vendor:/var/www/html/public/_resources/vendor:cached - ./composer.json:/var/www/html/composer.json
2. 修复容器用户权限
临时让Composer容器以root用户运行(生产环境建议配置用户ID映射),在composer服务中添加:
user: root
3. 手动验证复制逻辑
进入Composer容器手动执行复制命令,排查隐藏错误:
docker-compose run --rm composer bash # 模拟CopyMethod的复制操作,替换为实际需要复制的包路径 cp -r /var/www/html/vendor/[目标包]/public/* /var/www/html/public/_resources/vendor/
查看是否有权限报错或路径不存在的问题。
4. 简化卷配置
暂时移除ss-vendor-resources卷,只用绑定挂载到宿主机,确认复制逻辑正常后再考虑使用Docker卷。
内容的提问来源于stack exchange,提问作者tiller1010
相关产品推荐
相关产品推荐

