Background:
This docker cp out from container fail behaviour is a little bit quirky-funky so I think it should be documented. I couldn't find a matching question or docker issue but I can see chatter/comments which I think indicates people are encountering this.
I have a docker image and at image create time I pack up some directories in the image. When containers are started for the first time the directories are copied out of container and used to initialise a directory which is then mounted as docker volume for the container.
Problem:
What I was seeing was that depending on how image was built sometimes the docker cp out of directory would fail with "open <dir>/<file> permission denied" after doing a partial copy of directory.
I saw that when image was built locally by a developer it worked ok. I saw that when image was built from a released module that it failed.
Doing a docker cp out of the directory as root worked okay.
Doing a docker cp out of the directory as regular user did not work. The directory was created but was empty.
Directory permissions (weirdly of the source directories) turned out to be the cause of problem
This is a bit obvious BUT also not obvious; the top directory could be created okay so you would expect a recursive copy out of full directory hierarchy to work no matter what the permissions were of the SOURCE dirs.
Within source control directory ownership had write permission set. When modules were released the write permission was removed. So solution was when building using released modules the write permission had to be added back.
drwxr-xr-x dev/dev buildarea/.../jenkins/
drwxr-xr-x dev/dev buildarea/.../jenkins/email-templates/
dr-xr-xr-x root/root /releasearea/.../jenkins/
dr-xr-xr-x root/root /releasearea/.../jenkins/email-templates/
I see this with docker 17.03.1 centos cp from container July 2017.
Answer:
Because, somewhat weirdly, the source directory (i.e., in the container) is not writable.
Explanation:
Briefly: docker cp preserves permissions when copying a non-writable directory. So it fails when it tries to copy the first file into the target directory.
If you use docker cp to copy a directory as non-root user, and write permission is not set on a directory in the hierarchy (which contains files), then it will fail. The docker cp command will copy dirs and files until it creates a non-writable directory. When it tries to copy the first file into that non-writable directory, it fails with a message like:
Copying unlinkat <dir-which-is-not-writable>/<file>: permission denied.
Solution:
When creating directories in a docker image which will need to be copied out of your container using docker cp (as a non-root user), ensure that top level writable permission is set on every (non-empty) directory.
For example, in the Dockerfile you could add RUN find -type d -exec chmod u+w {} +. For an existing container, you could simply run the same find command from within the container.
Related issue: https://github.com/moby/moby/issues/3986#issuecomment-316966200
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With