从Docker容器复制文件到主机时遇Permission denied错误的原因及解决
Docker cp 权限拒绝错误分析与解决
问题场景
基于Alpine镜像创建包含test.txt的镜像,再创建容器后尝试将容器内的test.txt复制回主机时,出现权限拒绝错误,终端输出如下:
mdbl@mdblLXPS:~/Documents/research/docker/copying$ ls -ltr total 12 -rw-rw-r-- 1 mdbl mdbl 28 Jan 2 23:26 Dockerfile -rw-rw-r-- 1 mdbl mdbl 368 Jan 2 23:52 script.sh -rwxrwxrwx 1 mdbl mdbl 15 Jan 3 00:16 test.txt mdbl@mdblLXPS:~/Documents/research/docker/copying$ cat Dockerfile FROM alpine COPY test.txt . mdbl@mdblLXPS:~/Documents/research/docker/copying$ cat test.txt this is a test mdbl@mdblLXPS:~/Documents/research/docker/copying$ cat script.sh echo create the image sudo docker build -t testimg . echo echo list the newly created image sudo docker images | head -2 echo echo create the container sudo docker container create --name mycont testimg echo echo list the newly created container sudo docker container ls -a | head -2 echo echo try copying test.txt from the container sudo docker cp mycont:/test.txt . mdbl@mdblLXPS:~/Documents/research/docker/copying$ source script.sh create the image Sending build context to Docker daemon 4.096kB Step 1/2 : FROM alpine ---> 49176f190c7e Step 2/2 : COPY test.txt . ---> 70b40a27f26d Successfully built 70b40a27f26d Successfully tagged testimg:latest list the newly created image REPOSITORY TAG IMAGE ID CREATED SIZE testimg latest 70b40a27f26d Less than a second ago 7.05MB create the container 9c9396df4ab3e0538eb1aa995f13852d5328fbaa5597c82b731bb177cf809068 list the newly created container CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9c9396df4ab3 testimg "\"/bin/sh\"" Less than a second ago Created mycont try copying test.txt from the container unlinkat /home/mdbl/Documents/research/docker/copying/test.txt: permission denied
错误原因
核心原因是目标路径下已存在同名文件test.txt,docker cp在执行覆盖操作时需要先删除原文件,但主机的安全模块(如Ubuntu默认的AppArmor)限制了Docker守护进程(以root身份运行)修改用户Home目录下的普通用户文件。即便文件本身设置了全权限,目录层面的安全策略仍会阻止删除操作。
解决方法
方法1:先删除主机上的同名文件再复制
在执行docker cp前手动删除已存在的文件:
rm ~/Documents/research/docker/copying/test.txt && sudo docker cp mycont:/test.txt .
方法2:先复制到无权限限制的目录再移动
将文件先复制到/tmp这类root完全有权限的目录,再移动到目标路径:
sudo docker cp mycont:/test.txt /tmp/test.txt && sudo mv /tmp/test.txt ~/Documents/research/docker/copying/
方法3:临时关闭AppArmor对Docker的限制(不推荐长期使用)
如果只是临时测试,可以暂时关闭Docker的AppArmor规则:
sudo aa-disable docker-default
方法4:修改AppArmor规则(长期解决方案)
编辑Docker的AppArmor配置文件,添加允许访问目标目录的规则,具体步骤如下:
- 复制默认规则文件:
sudo cp /etc/apparmor.d/docker-default /etc/apparmor.d/docker-custom
- 在
docker-custom文件中,在profile docker-default flags=(attach_disconnected,mediate_deleted) {下方添加:
/home/mdbl/Documents/research/docker/copying/** rw,
- 加载新规则:
sudo apparmor_parser -r /etc/apparmor.d/docker-custom
- 重启Docker服务:
sudo systemctl restart docker
内容的提问来源于Stack Exchange,提问作者Mathew
相关产品推荐
相关产品推荐

