dockerdocker-composedocker-secrets

How to use 'mode' with docker secrets mounted with files?


I am testing Docker Secrets with long syntax. Unfortunately I something seems to be wrong or I cannot reproduce ownership / mode change as in following example from documentation:

version: "3.9"
services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    secrets:
      - source: my_secret
        target: redis_secret
        uid: '103'
        gid: '103'
        mode: 0440
secrets:
  my_secret:
    file: ./my_secret.txt
  my_other_secret:
    external: true

This seems to clearly state that my_secret is being sourced from file and there is possibility to set gid, uid and mode when mounted to specific location.

I've created following test docker-compose.yml file:

version: "3.9"
services:
  test:
    image: busybox:latest
    secrets:
      - source: secret_file
        target: /root/mysecretfile
        uid: '101'
        gid: '101'
        mode: 0400
    command: ls -alh /root

secrets:
  secret_file:
    file: ./docker-compose.yml

But running example shows that neither uid/gid nor permission to file has changed in container.

$ ls -alh docker-compose.yml 
-rw-r--r-- 1 devilan devilan 275 08-24 11:42 docker-compose.yml
$ docker compose up
[+] Running 1/0
 ⠿ Container secret-test-1  Created                                                                                                                                            0.0s
Attaching to secret-test-1
secret-test-1  | total 12K    
secret-test-1  | drwx------    1 root     root        4.0K Aug 24 09:41 .
secret-test-1  | drwxr-xr-x    1 root     root        4.0K Aug 24 09:41 ..
secret-test-1  | -rw-r--r--    1 1000     1000         275 Aug 24 09:42 mysecretfile

I am using one of the latest docker versions:

$ docker version
Client:
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.18.5
 Git commit:        100c70180f
 Built:             Thu Aug 18 11:20:14 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.5
  Git commit:       a89b84221c
  Built:            Thu Aug 18 11:38:13 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc:
  Version:          1.1.3
  GitCommit:        6724737f999df9ee0d8ca5c6d7b81f97adc34374
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad007797e0dcd8b7126f27bb87401d224240

Is this a bug or I am not understanding something from documentation properly?


Solution

  • I believe this is just a limitation for how docker compose implements the spec. The fields were originally added for Swarm Mode which loads the secret into the database, and pushes it to nodes in the swarm on a need to know basis. Those nodes load the file into a tmpfs file that gets mounted into the container, and in that tmpfs file, they are adjusting the permissions and ownership.

    With compose, I expect that to be implemented with a bind mount since there's no swarm manager and database to store the secrets in. And with a bind mount, there's no option to change the permissions and ownership between the source and target of the bind, the Linux kernel will pass those directly through.