PUID, PGID, and UMASK settings not working for custom app

I’m running beets as a custom app, using the images provided by linuxserver.io. I have my music library mounted as a host-path, and by opening a shell inside the container, I can use beets to organize my library, import new music, update metadata tags, etc.

The issue is that it always creates files with the following modes:

  • Files: root:apps 644 (-rw-r--r--)
  • Directories: root:apps 755 (drwxr-xr-x)

This is no good, because it revokes write access from the apps user every time a file gets imported or put in a new directory. Ideally, everything would be apps:apps (or maybe myUser:apps) with modes 664 and 775.

The documentation from LSIO explains that the PUID, PGID, and UMASK environment variables are supposed to change this. I’ve set them through the TrueNAS Web UI, but it doesn’t have any effect!

It is at least possible to manually chmod files to 664/774 or whatever mode from inside the container; chown works too.

568 is a TrueNAS-specific id, so I don’t think it’s hardcoded into the LSIO image. Could TrueNAS be interfering in the PUID/PGID/umask settings? How can I fix this?

Still not sure what was wrong with the LSIO image, but I ultimately fixed this issue by switching to beets-flask. Now it’s possible to run commands like this: docker exec -u 568:568 ix-beets-flask-beets-flask-1 beet mbsync

The above command runs within the container as user 568 (“beetle”). Beets-flask does this without complaint; meanwhile, it’s impossible to run commands as user 586 (“abc”) in the LSIO image. The init process never hands-off from root to abc either in LSIO. Maybe something is just wrong with their image.

Still interested if any Docker gurus can weigh in here. Beets-flask seems nice but I’d still prefer to use plain old upstream Beets if it worked.

As you can see, docker has it’s own internal way of running containers as a specific user. You can do it in docker compose like such:

services:
  myservice:
    image: myimage
    user: "1000:1000" # or "myuser:myuser"

Thanks for your reply.

Before starting this thread, I did experiment with the Web UI’s “Custom User” option – I think this is equivalent to the dockerfile UID/GID settings.

Running as 568:568 seems to make the container pretty unhappy, with whoami complaining before every prompt:

@a492b18ae9b8:/mnt/Music$ pwd
/mnt/Music
whoami: cannot find name for user ID 568
@a492b18ae9b8:/mnt/Music$ whoami
whoami: cannot find name for user ID 568
whoami: cannot find name for user ID 568

This is quite a nuisance, since beets is a command-line program!

I also see that the placeholder user abc never gets set to its proper UID/GID according to /etc/passwd. It’s still set to 911:911:

@a492b18ae9b8:/mnt/Music$ cat /etc/passwd
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
guest:x:405:1000:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
klogd:x:100:101:klogd:/dev/null:/sbin/nologin
abc:x:911:1001::/config:/bin/false
whoami: cannot find name for user ID 568

But setting up abc’s UID/GID doesn’t matter, since all processes are running under UID 568; none under root or abc:

@a492b18ae9b8:/mnt/Music$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
568            1  0.0  0.0    440     0 ?        Ss   22:39   0:00 /package/admin/s6/command/s6-svscan -d4 -- /r
568           21  0.0  0.0    220     0 ?        S    22:39   0:00 s6-supervise s6-linux-init-shutdownd
568           24  0.0  0.0    208     0 ?        Ss   22:39   0:00 /package/admin/s6-linux-init/command/s6-linux
568           40  0.0  0.0    220     0 ?        S    22:39   0:00 s6-supervise svc-beets
568           41  0.0  0.0    220     0 ?        S    22:39   0:00 s6-supervise s6rc-oneshot-runner
568           42  0.0  0.0    220     0 ?        S    22:39   0:00 s6-supervise svc-cron
568           43  0.0  0.0    220     0 ?        S    22:39   0:00 s6-supervise s6rc-fdholder
568           51  0.0  0.0    208     0 ?        Ss   22:39   0:00 /package/admin/s6/command/s6-ipcserverd -1 --
568          160  0.0  0.0   2388  1280 ?        Ss   22:39   0:00 bash ./run svc-cron
568          161  0.4  0.0 419264 60700 ?        Ssl  22:39   0:02 /lsiopy/bin/python3 /lsiopy/bin/beet web
568          179  0.0  0.0   7612  1544 ?        S    22:39   0:00 sleep infinity
568          210  0.0  0.0   1724   696 pts/0    Ss   22:39   0:00 sh
568          291  0.0  0.0   2936  1624 pts/0    R+   22:48   0:00 ps aux
whoami: cannot find name for user ID 568

I guess this is all expected behavior. We’re brute-forcing the container to run as 568, which screws up the s6 init system, prevents editing /etc/passwd, etc. LSIO gave us the heads-up about this here: Running Containers As A Non-Root User - LinuxServer.io

Anyway – with this option set, new files are created as 568:568, so this does technically accomplish my goal. But the container seems a little broken this way, and the docs seem to make it clear that PUID/PGID are the intended way to do this.

I should try running this same LSIO image on a non-TrueNAS system; maybe it’s just a bug in their release. But beets-flask has been working perfectly, so I’ve lost my motivation to chase this one down :sweat_smile: