Docker创建容器报错cannot mount volume over existing file
问题根因
该报错是Docker执行bind mount操作时的规则冲突:Docker要求挂载源(宿主机路径/命名卷)和容器内目标路径的文件类型必须完全匹配(文件对应文件、目录对应目录),如果出现目录往文件路径上挂载、或者存储层残留旧挂载标记,就会抛出该异常,常见触发场景共三类:
- Docker守护进程配置了全局默认挂载规则(最常见的是默认挂载宿主机时区到容器内),规则里将宿主机的时区目录挂载到容器内
/usr/share/zoneinfo/UTC这个独立文件路径上,触发类型冲突 - 之前创建同镜像/同名容器时发生过崩溃、强制删除操作,对应overlay2存储层的merged目录未被正常回收,残留了旧的挂载标记文件,新容器创建时复用存储缓存触发冲突
- 自定义镜像
php7.3-centos7.6:v1.4构建时存在配置错误,Dockerfile中误将/usr/share/zoneinfo/UTC路径声明为卷挂载点,但镜像内该路径实际是普通时区文件,启动时自动挂载触发冲突
排查解决步骤
按优先级从高到低操作:
- 第一步:清理残留容器与脏存储缓存
先查找所有状态的同名残留容器:docker ps -a | grep php-test-docker
查到后直接强制删除:docker rm -f php-test-docker
执行命令清理悬空存储层、未使用的卷缓存:docker system prune -f --volumes
清理完成后直接重试启动命令,大部分残留导致的冲突可以直接解决。 - 第二步:检查Docker全局挂载配置
打开守护进程配置文件:vi /etc/docker/daemon.json
查找是否有全局默认挂载配置项,重点排查时区相关的挂载规则,如果存在将目录路径挂载到容器内/usr/share/zoneinfo/UTC文件路径的规则,直接删除该错误配置,或调整挂载源为具体的时区文件,保证挂载两端类型一致。修改完成后重启Docker服务生效:systemctl restart docker - 第三步:修正原启动命令的写法错误
原启动命令存在两处问题:一是给shell启动命令额外套了一层双引号,会被Docker识别为一个完整的可执行文件名导致执行异常;二是php-fpm路径写的是相对路径,容器内工作目录不对时会找不到执行文件。修正后的可直接运行的命令如下:
如果业务需要同步宿主机时区,显式加只读的文件挂载即可,禁止将目录挂载到容器内的文件路径:docker run -d --name php-test-docker \ -v /home/docker-data/php-test-docker:/var/www/ \ -p 9009:9000 \ -p 1219:1215 \ php7.3-centos7.6:v1.4 \ /bin/sh -c /usr/sbin/php-fpm-v /etc/localtime:/etc/localtime:ro - 第四步:排查镜像本身的构建问题
如果以上操作全部完成后仍然复现报错,说明自定义镜像构建时存在错误配置,可以先启动一个临时同基础镜像的容器,进入容器内检查/usr/share/zoneinfo/UTC的文件属性,以及镜像内是否有错误的卷声明,重新构建镜像时移除错误的卷配置即可。
内容的提问来源于stack exchange,提问作者willis-yang
相关产品推荐
相关产品推荐

