Docker user inside of container is "unset" #9820

I set up a fresh docker in rootless mode on a Rocky Linux, then migrated all my containers by unziping a backup and just “docker compose up” into each services. But I faced the following error of file permissions “Failed to load/generate certificate: save cert: open /var/syncthing/config/cert.pem: permission denied”.

After oppening a shell into the container, I found that the user with the “UID” and “GUID” 1000 is not present. So it’s logical that I don’t have the permission to access the file.

Am I bad at files permissions or is it the container image that is wrongly set up ?

Relevant log output

❯ docker compose up
[+] Running 1/0
 ✔ Container syncthing  Recreated                                                                                                                                                                                                                                                0.0s 
Attaching to syncthing
syncthing  | [start] 2024/11/12 20:50:23 INFO: syncthing v1.28.0 "Gold Grasshopper" (go1.23.2 linux-arm64) docker@github.syncthing.net 2024-10-04 19:47:57 UTC [noupgrade]
syncthing  | [start] 2024/11/12 20:50:23 INFO: Generating ECDSA key and certificate for syncthing...
syncthing  | [start] 2024/11/12 20:50:23 WARNING: Failed to load/generate certificate: save cert: open /var/syncthing/config/cert.pem: permission denied
syncthing  | [monitor] 2024/11/12 20:50:23 INFO: Syncthing exited: exit status 1
syncthing  | [start] 2024/11/12 20:50:24 INFO: syncthing v1.28.0 "Gold Grasshopper" (go1.23.2 linux-arm64) docker@github.syncthing.net 2024-10-04 19:47:57 UTC [noupgrade]
syncthing  | [start] 2024/11/12 20:50:24 INFO: Generating ECDSA key and certificate for syncthing...
syncthing  | [start] 2024/11/12 20:50:24 WARNING: Failed to load/generate certificate: save cert: open /var/syncthing/config/cert.pem: permission denied
syncthing  | [monitor] 2024/11/12 20:50:24 INFO: Syncthing exited: exit status 1
syncthing  | [start] 2024/11/12 20:50:25 INFO: syncthing v1.28.0 "Gold Grasshopper" (go1.23.2 linux-arm64) docker@github.syncthing.net 2024-10-04 19:47:57 UTC [noupgrade]
syncthing  | [start] 2024/11/12 20:50:25 INFO: Generating ECDSA key and certificate for syncthing...
syncthing  | [start] 2024/11/12 20:50:25 WARNING: Failed to load/generate certificate: save cert: open /var/syncthing/config/cert.pem: permission denied
syncthing  | [monitor] 2024/11/12 20:50:25 INFO: Syncthing exited: exit status 1
syncthing  | [start] 2024/11/12 20:50:26 INFO: syncthing v1.28.0 "Gold Grasshopper" (go1.23.2 linux-arm64) docker@github.syncthing.net 2024-10-04 19:47:57 UTC [noupgrade]
syncthing  | [start] 2024/11/12 20:50:26 INFO: Generating ECDSA key and certificate for syncthing...
syncthing  | [start] 2024/11/12 20:50:26 WARNING: Failed to load/generate certificate: save cert: open /var/syncthing/config/cert.pem: permission denied
syncthing  | [monitor] 2024/11/12 20:50:26 INFO: Syncthing exited: exit status 1
^CGracefully stopping... (press Ctrl+C again to force)
[+] Stopping 1/1
 ✔ Container syncthing  Stopped                                                                                                                                                                                                                                                  1.7s 
canceled

a container is mostly just a file system snapshot, and a process running a fancy “chroot”.

The files in the image have to be owned by someone, in this case it’s 1000.

Who (as in, which user) you launch the process as, is your choice, we expect you to launch it as user 1000 (even if it does not exist on your operating system).

This is what docker would do by default if you didn’t specify a user to run as.

The fact you are running as something else than 1000 suggests you are setting a custom user, or not using our images.

Hi, thank’s for the answer :slight_smile: Hmmm, this is my compose.yml file :

name: syncthing

services:
  syncthing:
    image: syncthing/syncthing
    container_name: syncthing
    #hostname: my-syncthing
    #user: rocky
    environment:
      - PUID=1000
      - PGID=1000
      - UMASK=007
      - PCAP=cap_chown,cap_fowner+ep
    volumes:
      - ./data:/var/syncthing
    restart: unless-stopped

I do not set a custom user and use your image :thinking:

The folder and files permissions are the following

❯ ls -lah ./data/
[...]
drwxrwx---. 3 rocky  rocky   122 Jul 28 08:33 config

❯ ls -lah data/config/
total 36K
drwx------. 3 rocky  rocky  122 Jul 28 08:33 .
drwxr-xr-x. 7 100999 100999  82 Nov  5 19:47 ..
-rw-rw-r--. 1 rocky  rocky  794 Jul  3  2023 cert.pem
-rw-rw----. 1 rocky  rocky  20K Jul 28 08:33 config.xml
-rw-rw-r--. 1 rocky  rocky  806 Jul  3  2023 https-cert.pem
-rw-rw----. 1 rocky  rocky  288 Jul  3  2023 https-key.pem
drwxrwxr-x. 2 rocky  rocky  176 Oct 30 07:45 index-v0.14.0.db
-rw-rw----. 1 rocky  rocky  288 Jul  3  2023 key.pem

I run docker as non root So the docker daemon and all containers run as my user (rocky) and not root. What is wrong ? I don’t get it.

It’s not clear what uid rocky is, but it’s likely that you started the container with a user other than 1000, which bootstrapped the config and database with the wrong user (not 1000), and now even if you switch to 1000, the files are now owned by the wrong user and things don’t work.

The id command gives :

❯ id
uid=1000(rocky) gid=1000(rocky) groups=1000(rocky),[...]

So everything seems consistent :thinking:

What command do I need to do to make the container “re own” with the good permissions ? Because yeah I ZIP the entire folder then uploaded the file to another instance (from an Ubuntu docker ROOT → rocky linux docker non root).

Based on the sequence of commands, I’m assuming that the output from id was from the host side rather than within the container.

Regardless, it’s best to be specific when asking for help, especially when using a custom shell prompt.

Maybe, or maybe not. A snippet from your earlier post:

Although data/config and the files in it are owned by rocky:rocky, the parent folder data/ is owned by 100999:100999.

Uh, no…

In Unix/Linux, /etc/passwd and /etc/group are just lookup tables for user-friendly user and group names, home directory path, preferred shell, etc. They don’t prevent files from being created or processes running under a nonexistent UID:GID.

For example, there’s no issue creating a file owned by the likely nonexistent user 12345:12345:

touch /tmp/testfile ; chown 12345:12345 /tmp/testfile ; ls -l /tmp/testfile

Subordinate UIDs and GIDs…

On the host side, /etc/subuid and /etc/subgid set the base UID and GID used for the offsets (check the manpages for subuid and subgid for more details).

So if the base is 100000 with PUID and PGID both at 1000, then inside the container a file owned by 1000:1000 will be 100999:100999 on the host side.

User root inside the container is 0:0, but outside the container it’s going to be 1000:1000 (i.e. rocky:rocky in your host).

(Note that while your compose.yml sets PUID and PGID to 1000, which is fine, it doesn’t actually change anything because the official Syncthing image already runs Syncthing as user 1000:1000 inside the container.)

(And on a related note, since you want to run Docker in rootless mode, and you’re using Rocky Linux, considering switching to Podman instead.)

Ok I used

chown 100999:100999 ./data

It works now.

Thank you !

I wanted to know more of this sub-uid/gid concept, do you have any ressources I can read ?

And yeah I know podman, but I’m used to docker and wan’t to stick with it for now :slight_smile: