Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Docker user settings #539

Open
Silther opened this issue Dec 26, 2024 · 8 comments
Open

[FEATURE] Docker user settings #539

Silther opened this issue Dec 26, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@Silther
Copy link

Silther commented Dec 26, 2024

Is your feature request related to a problem?

Docker allows to set the user directly without the environment, which is preferable. As it makes it more secure and less complex.

Describe the solution you'd like

services:
  stump:
    container_name: stump
    image: aaronleopold/stump:latest
    restart: unless-stopped
    user: "1001:1001"                # <-- specify user here
    user_add:
      - "1002" # media
    ports:
      - "8080:10801"
    volumes:
      - /home/docker/volumes/stump/config:/config
      - /data/media/books:/books
    # environment:
    #   - PUID=1001
    #   - PGID=1001
    env_file:
      - stack.env

Additional context

Currently setting user with "user: 1000:1000" breaks for me.

@Silther Silther added the enhancement New feature or request label Dec 26, 2024
@aaronleopold
Copy link
Collaborator

Currently setting user with "user: 1000:1000" breaks for me

Can you describe what happens? Or share the output?

@Silther
Copy link
Author

Silther commented Dec 26, 2024

image

user: "1001:1001"
group_add:
  - "2001" # media

1001 is my docker user and access to media works, but I get those errors.

@Silther
Copy link
Author

Silther commented Dec 26, 2024

if I try to create a library with out having the correct permissions I get this error:

Construction illustration
A critical error occurred

Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7Bstatus%2C%20message%7D
Fm@https://stump.domain.de/assets/index-673c0d5b.js:38:12804
v@https://stump.domain.de/assets/index-673c0d5b.js:38:17864
hn@https://stump.domain.de/assets/index-673c0d5b.js:40:1475
G3@https://stump.domain.de/assets/index-673c0d5b.js:40:45764
V3@https://stump.domain.de/assets/index-673c0d5b.js:40:39789
wX@https://stump.domain.de/assets/index-673c0d5b.js:40:39717
lv@https://stump.domain.de/assets/index-673c0d5b.js:40:39568
r1@https://stump.domain.de/assets/index-673c0d5b.js:40:35933
F3@https://stump.domain.de/assets/index-673c0d5b.js:40:34882
x@https://stump.domain.de/assets/index-673c0d5b.js:25:1554
L@https://stump.domain.de/assets/index-673c0d5b.js:25:1915

@aaronleopold
Copy link
Collaborator

So it seems using user and group_add breaks all of the init logic in the entrypoint for docker, based off of all of the permission denied errors you showed on startup. I'm assuming this affects the config directory, too, which likely causes db connect errors and/or write issues. This is just because it expects the p(g/u)ids from the env, but I'm not sure offhand how to account for these alternate docker settings. I'll try to look into it sometime after the new year, but would appreciate any linux/docker wizards giving their input if possible

@kulak
Copy link

kulak commented Jan 1, 2025

For what it is worth, I had to disable entry point script when configuring rootless container under podman. It was the most difficult part to figure out with stump image.

Please, take a note of comment below Because the image has "Config":{User:0} it always runs with root ID. I am not sure if the statement can be equally applied if run under docker.

See complete configuration for all of the contextual data: #512

Podman configuration highlights:

# This option is usually sufficient for rootless to run with target UID and GID, but not in stump image case
UserNS=keep-id
# Becausethe image has "Config":{User:0} it always runs with root ID, 
# force to match UserNS=keep-id above, this is specific to THIS image
User=your_desired_user_id
Group=your_desired_group_id

# Disable /entrypoint.sh code
Entrypoint=/app/stump

@aaronleopold
Copy link
Collaborator

For what it is worth, I had to disable entry point script when configuring rootless container under podman. It was the most difficult part to figure out with stump image.

Sounds like there should be some additional configuration options for the entrypoint script so folks don't have to have custom workarounds 🙂

I'll try and look into what might be useful to configure at this step sometime soon

@kulak
Copy link

kulak commented Jan 1, 2025

Sounds like there should be some additional configuration options for the entrypoint script so folks don't have to have custom workarounds 🙂

Point 1

My podman experience made me think that stump image might be easier to manage if entrypoint script did not exist. It is an example of getting more with less effort.

Instead of trying to override or parametrize the script, omitting the script allows end user to apply engine specific features of running rootless, if necessary.

Point 2

When I tested stump I run other images to compare rootless environments and I found that stump image was behaving differently from other images I tested. Which sent me into hours of figuring out why this image behaved differently.

In the end it was not so much entrypioint.sh script itself, but image configuration setting "Config":{User:0}. I am not sure what triggers this configuration in the image, but I suspect it is related to setting user id in Dockerfile.

I would speculate, that removing configuration "Config":{User:0} option from the image will result in even simpler rootless configuration in podman. In this case entrypoint script will not be necessary either.

Use command to inspect image and then locate Config section with User:0 in it:

podman image inspect docker.io/aaronleopold/stump:0.0.9 | less

Examples

I found that simple images that don't try to manage UID and GID are easy to control from rootless perspective. Examples:

  • docker.io/bash
  • docker.io/traefik/whoami:latest

Images that attempt to manage UID and GID are actually hard to control and require inspection of what they do:

  • docker.io/aaronleopold/stump:0.0.9
  • ghcr.io/mealie-recipes/mealie:v2.4.1 (I have setup 1000 for it, but host ID is a very large number; that's normal, but it does not help when trying to control host ID)

Thoughts on Sharing

Actually, explicit control of UID and GID at host level is only important in one case: sharing host file system with container application.

There are 2 types of sharing:

  • sharing with native apps like nginx, Samba or NFS
  • sharing with other containers

I am looking at the problem when SELinux environment is enabled (Fedora, Alma Linux, etc).

Sharing among containers is taken care off by containerization and volume sharing with Z and z options.

Sharing with Samba seems to have its own option, but it did not work for me as expected. In the end sharing with native apps is when we try to control UID and GID.

In my case I decided that sharing with native apps like samba can be very difficult especially in case of write access.

My solution was to switch from native Samba, to containerized rootful Samba to reduce the complexity and to rely on container sharing.

Final Thoughts

Due to all of the above complexity I would recommend that simplest solution is not to try to manage UID and GID of the service application. Let the administrator set what they want containerized application to run as and be done with it.

It is relatively easy for someone to derive an image and to configure UID and GID however they want if original image had not attempted to manage its users.

This resource is one of the best on the topic of identifying what process application runs as Understanding root inside and outside a container.

The topic of controlling user is vast and has a lot of fine detail. This is just a starting point: Controlling user of containerized application.

@kulak
Copy link

kulak commented Jan 1, 2025

The cause of the "permission denied" above is line in entrypoint.sh script:

addgroup -g $PGID $GROUP

addgroup -g $PGID $GROUP
adduser -u $PUID -G $GROUP -D -H $USER

The above lines require root to run properly.

When container engine switches user id to non-root, then the above lines break, which probably causes other bad effects, because specifying PUID and PGID environment variables no longer has effect in entrypoint.sh script:

PUID=${PUID:-0}
PGID=${PGID:-0}

Now we have image that is running under a specific UID and GID, but it does NOT have entries for these UID and GID in /etc/ files, because we failed to create that user and group. that's only true if environment variables PUID and PGID don't match containerization environment UID and GID settings. If they match, then in podman case, podmain will autogenerate UID and GID entries in required files (from my observation).

That's the core of the problem when trying to manage user and group using container options for user.

The simplest not to deal with different cases is not to deal with any of the cases and to have no entrypoint logic related to user management.

I kind of arrived to the same conclusion from two different perspectives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants