Currently Linux containers are still more popular than Windows containers. And Windows users often need to use Linux containers even from their Windows computers.

Recently I’ve found something very strange about Linux-style file permissions when the Docker images are built from Windows hosts.1 Therefore, I’ve conducted a suite of test cases to investigate whether file permissions are preserved with Docker & Skaffold toolchains. All experiment materials are available in the container-chmod repo.

% git clone https://github.com/William-Yeh/container-chmod.git

Experiment setting

The experiments are composed of a few files with typical Unix-style file permissions:

.
├── skaffold.yaml
└── src
    ├── Dockerfile
    ├── file-644.txt
    └── script-755.sh

-rw-r--r-- 1 william  70 Jun 24 17:01 Dockerfile
-rw-r--r-- 1 william  57 Jun 24 15:17 file-644.txt
-rwxr-xr-x 1 william  84 Jun 24 15:19 script-755.sh

We will use two ways to build the Linux-container images:

  1. To build image with docker build command (Docker Engine 18.09.2).

  2. To build image with skaffold build command (Skaffold v0.32.0).

And we’ll conduct the experiments in the following environment settings:

Host Built w/ Docker CLI Built w/ Skaffold (WSL version) Built w/ Skaffold (host version)
macOS N/A
WSL + Docker Desktop for Windows N/A
Windows N/A

Will all experiments display the correct file permissions?

macOS: ➊ ➋

Let’s begin with macOS, which acts as the control group.

asciicast

Perfect! All Unix-style file permissions are set correctly.

total 20                                                                        
drwxr-xr-x    1 root     root          4096 Jun 24 22:30 .                      
drwxr-xr-x    1 root     root          4096 Jun 24 22:30 ..                     
-rw-r--r--    1 root     root            70 Jun 24 22:18 Dockerfile             
-rw-r--r--    1 root     root            57 Jun 24 22:18 file-644.txt           
-rwxr-xr-x    1 root     root            84 Jun 24 22:18 script-755.sh          

WSL: ③ ➍

On Windows, my preference is to use WSL to connect to Docker Desktop for Windows.2 Will this combination work well with Unix-style file permissions?

Below are experiments conducted on WSL:

asciicast

As shown in this demo, the ➍ skaffold experiment works quite well on WSL. The ③ docker-cli experiment works, though not the best-possible Unix-style file permissions:3

SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Pure Windows: ⑤ ⑹

What if a Windows user sticks with pure-Windows toolchains, i.e., use traditional Command Prompt (cmd) to connect to Docker Desktop for Windows?

The ⑤ docker-cli experiment shows the same result as in previous ③ '-rwxr-xr-x' permission:

C:\> docker run -it test-docker                                           
File permission (script-755.sh) should be: 755  rwxr-xr-x              
total 20                                                               
drwxr-xr-x    1 root     root          4096 Jun 25 03:45 .             
drwxr-xr-x    1 root     root          4096 Jun 25 03:45 ..            
-rwxr-xr-x    1 root     root            70 Jun 25 03:44 Dockerfile    
-rwxr-xr-x    1 root     root            57 Jun 24 08:03 file-644.txt  
-rwxr-xr-x    1 root     root            84 Jun 24 08:03 script-755.sh

However, the ⑹ skaffold experiment shows the worst result:

C:\> skaffold-windows-amd64.exe build
Generating tags...
 - test-skaffold -> test-skaffold:dbe377c
Tags generated in 228.0023ms
Starting build...
Found [docker-for-desktop] context, using local docker daemon.
Building [test-skaffold]...
Sending build context to Docker daemon  4.096kB
Step 1/4 : FROM alpine:3.9.4
...


C:\> docker run -it 25997136449a
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344:
starting container process caused "exec: \"/app/script-755.sh\": permission denied": unknown.


C:\> docker run -it 25997136449a  ls -al
total 20
drwxr-xr-x    1 root     root          4096 Jun 25 03:51 .
drwxr-xr-x    1 root     root          4096 Jun 25 03:53 ..
-rw-rw-rw-    1 root     root            70 Jun 25 03:44 Dockerfile
-rw-rw-rw-    1 root     root            57 Jun 24 08:03 file-644.txt
-rw-rw-rw-    1 root     root            84 Jun 24 08:03 script-755.sh

As shown in the demo, Skaffold blindly sets all the file permissions as '-rw-rw-rw-', eliminating the 'x' permission required for the script-755.sh script file.

Conclusion

Different Unix-style file permissions will be generated in the Docker images when building Linux containers with different combination of host operating systems, docker cli, and Skaffold toolchains:

Host Built w/ Docker CLI Built w/ Skaffold (WSL version) Built w/ Skaffold (host version)
macOS N/A
WSL + Docker Desktop for Windows N/A
Windows N/A

Results:

  • Best results: ➊ ➋ ➍
  • Acceptable results: ③ ⑤
  • Unacceptable results: ⑹

My suggestions for building Linux images are:

  • If your applications require adequate file permissions (especially the 'x') and you cannot completely control the build toolchains to use, be sure to modify your Dockerfile accordingly.

  • If you can control the whole toolchains to use (e.g., in the CI/CD pipeline), stick with the Linux ones.