Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Docker COPY doesn't change file permissions? (--chmod)

Given this Dockerfile:

FROM docker.io/alpine

RUN mkdir test

# RUN umask 0022
COPY README /test/README
COPY --chmod=777 README /test/README-777
COPY --chmod=755 README /test/README-755

COPY FORALL /test/FORALL
COPY --chmod=777 FORALL /test/FORALL-777
COPY --chmod=755 FORALL /test/FORALL-755

RUN ls -la /test

I'd expect to have the read, write, execute permissions be set accordingly by Docker during the build process (docker build ./).

But the last command returns

total 8
drwxr-xr-x    1 root     root          4096 Jun  9 19:20 .
drwxr-xr-x    1 root     root          4096 Jun  9 19:20 ..
-rwxrwxrwx    1 root     root             0 Jun  9 19:19 FORALL
-rwxrwxrwx    1 root     root             0 Jun  9 19:19 FORALL-755
-rwxrwxrwx    1 root     root             0 Jun  9 19:19 FORALL-777
-rw-rw-r--    1 root     root             0 Jun  9 19:19 README
-rw-rw-r--    1 root     root             0 Jun  9 19:19 README-755
-rw-rw-r--    1 root     root             0 Jun  9 19:19 README-777

No file permission was changed, and no error was raised.

Why doesn't it work?
How to fix this?

like image 697
Kamafeather Avatar asked Jun 09 '21 19:06

Kamafeather


People also ask

How do you copy permissions in Linux?

You can use the -p option of cp to preserve the mode, ownership, and timestamps of the file. However, you will need to add the -r option to this command when dealing with directories. It will copy all sub-directories and individual files, keeping their original permissions intact.

How does copy work in docker?

COPY is a docker file command that copies files from a local source location to a destination in the Docker container. ADD command is used to copy files/directories into a Docker image. It only has only one assigned function. It can also copy files from a URL.

What does chmod 0755 mean?

When you perform chmod 755 filename command you allow everyone to read and execute the file, the owner is allowed to write to the file as well. So, there should be no permission to everyone else other than the owner to write to the file, 755 permission is required. Hope this helps you!


2 Answers

I figured out:
the flag --chmod is a new feature from Docker Buildkit, so it is necessary to run the build enabling it via:

DOCKER_BUILDKIT=1 docker build ./

However, it is really not clear why Docker swallows the --chmod option without any error or warn about the non-existing option 😕.

like image 137
Kamafeather Avatar answered Oct 16 '22 10:10

Kamafeather


This is fixed in 20.10.6 (pull request, tracking issue):

$ cat df.chmod 
FROM busybox as base

RUN touch /test

FROM busybox as release
COPY --from=base --chmod=777 /test /test-777
COPY --from=base --chmod=555 /test /test-555
CMD ls -l /test*

$ DOCKER_BUILDKIT=0 docker build -t test-chmod-classic -f df.chmod .
Sending build context to Docker daemon  22.02kB
Step 1/6 : FROM busybox as base
 ---> a9d583973f65
Step 2/6 : RUN touch /test
 ---> Running in ed48f45a5dca
Removing intermediate container ed48f45a5dca
 ---> 5606d2d23861
Step 3/6 : FROM busybox as release
 ---> a9d583973f65
Step 4/6 : COPY --from=base --chmod=777 /test /test-777
the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled

And if the build is run with buildkit, the expected result occurs:

$ DOCKER_BUILDKIT=1 docker build -t test-chmod-buildkit -f df.chmod .
[+] Building 1.0s (8/8) FINISHED
 => [internal] load build definition from df.chmod                                                                                    0.0s
 => => transferring dockerfile: 214B                                                                                                  0.0s
 => [internal] load .dockerignore                                                                                                     0.0s
 => => transferring context: 49B                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/busybox:latest                                                                     0.0s
 => CACHED [base 1/2] FROM docker.io/library/busybox                                                                                  0.0s
 => [base 2/2] RUN touch /test                                                                                                        0.6s
 => [release 2/3] COPY --from=base --chmod=777 /test /test-777                                                                        0.1s
 => [release 3/3] COPY --from=base --chmod=555 /test /test-555                                                                        0.1s
 => exporting to image                                                                                                                0.0s
 => => exporting layers                                                                                                               0.0s
 => => writing image sha256:a4df92175046e36a72a769f9c7b297bc04a825708c5f6ca5873428b55c340036                                          0.0s
 => => naming to docker.io/library/test-chmod-buildkit                                                                                0.0s

$ docker run --rm test-chmod-buildkit
-r-xr-xr-x    1 root     root             0 Jun 10 13:00 /test-555
-rwxrwxrwx    1 root     root             0 Jun 10 13:00 /test-777
like image 9
BMitch Avatar answered Oct 16 '22 09:10

BMitch