3

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.

gaoithe
  • 4,218
  • 3
  • 30
  • 38
  • I have answered my own question here I know :-7. Surprised stackoverflow didn't contain this question already. Hopefully is of use and will reduce some confusion around docker cp. – gaoithe Jul 21 '17 at 11:08
  • 1
    Then move your solution on an answer. Sometimes we find solutions while describing the problem and there is nothing wrong with answering your own question here on SO. – Grimmy Jul 21 '17 at 11:28

3 Answers3

5

Answer:

Because, somewhat weirdly, permissions on source directory is not writable. And that affects writing files into that directory during the 'docker cp'.

Explanation:

docker cp creates directory without write permission set. Then fails to write files into it.

If you docker cp out a directory as root then the directory is recursively copied out okay. If you docker cp out a directory as non-root user and write permission is not set on a directory in the hierarchy which contains something then the docker cp command will copy dirs and files until it creates the non-writable directory and then fails to copy next file into that not-writeable directory with "open ; permission denied".

Solution:

At Dockerfile or docker build time when creating directories in docker image which will be copied out of container using docker cp (as not root user) then ensure that top level writeable permission is set on each directory. e.g. 'find -type d -exec chmod +w {} +'.

https://github.com/moby/moby/issues/3986#issuecomment-316966200

gaoithe
  • 4,218
  • 3
  • 30
  • 38
0

As already mentioned, directory permissions are the first thing to check. In particular, it's not enough if a folder being accessed has the right permissions set -- its parent folders (up to your home directory) need to have at least List directory permission. See also my answer here.

However, what solved the problem of

cp: can't open '/directory/./file': Permission denied

in my case was Windows EFS (Encrypting File System). Make sure that no files or folders in the source are encrypted on a file-system basis. Docker tries to access the file system from Linux and will, unlike Windows, not transparently decrypt files while reading.

Encryption can be toggled by right-clicking a file/folder, then Properties > General tab > Advanced button > Encrypt contents to protect data.

TheOperator
  • 5,936
  • 29
  • 42
0

A hacky way to deal with this would be to elevate file permissions on your local machine and then copy that into the container.

chmod 777 source_file.txt # <-- this is unsafe (change to a better set of permissions)
docker cp source_file.txt <container>:/path/to/file.txt

Your container can now run that file as a root or non-root user.

roshnet
  • 1,695
  • 18
  • 22