Compose: Allow use of dynamic user in fig

Created on 9 Feb 2015  路  19Comments  路  Source: docker/compose

It would be nice if fig could do the same as:

docker run --rm -i --user="$(id -u):$(id -g)" ubuntu /bin/bash -v $PWD:/data

This way one would be able to set the same user user/group as the current user without having to set manually each time for every different user.

(using this would make the files created within the container to be with the same permission of the actual user)

Most helpful comment

With environment interpolation and user: in the yml, this is now supported.

We also have --user on docker-compose run

Why only on the run command and not on up?
I'm asking because currently we implement docker-compose for a load-test with Jenkins pipelines. The pipeline is able to detect the user id of the "jenkins" user on the current node, but this does not have to be always the same. Also you really don't want to rebuild all docker images you are using for a CI system just to ensure a user named "jenkins". This is what we have left behind with Jenkins v1 and we don't want it back. ;)

If there is a way to use run for load tests without having the build job stuck in a never closing docker-compose thread (that's what I just got fixed with docker-compose up --exit-code-from <SERVICE>), I would be happy to hear from. Otherwise I would prefer having the --user flag on docker-compose up, too.

Also I agree with PandaaRun that using user ids is much more properly done than using user names.

All 19 comments

A very similar feature like this has been suggested in #495

This is not related to #495. I think it's part of #363

What's the use case?

With environment variable support, passing in $USER will be trivial. Not true for groups though.

@aanand From what I can tell, these two fig.yaml files behave very differently:

Setting user directly:

server:
  image: artificial/docker-sails:stable-pm2
  volumes:
    - server/:/server
  user: 1000

Setting USER environment variable:

server:
  image: artificial/docker-sails:stable-pm2
  volumes:
    - server/:/server
  environment: 
    - USER=1000

In the first case, when setting the user, files generated with a fig run server sails new . creates a new sails project inside the /server directory with ownership of 1000:0 which is what I want in this case. I see this same behavior when using fig run -e USER=1000 server sails new .

However, when setting the environment variable "USER", the files are all still created with 0:0 (root:root). I see this same behavior when using fig run -e USER=1000 server sails new . All the files are still owned by root, even though a fig run server env confirms that USER=1000

It would be really nice to be able to set the user in the fig run command, as suggested in this issue report, because then I could control the ownership of the files being created.

737 is related to this

Using the approach I proposed in #1006 we could provide a safe variable substitution.

This could include eg: %%user%% and %%group%% variables.

Those variables will be resolved via python (and not prone to shell-expansion)

It would be nice if you could have environment variables in docker-compose.yml that are substituted by python when the file is read. For example, you could have user: $UID in a service so it runs as the same user that is running docker-compose. This is useful for development scenarios among other things where containers might generate files you then want to edit.

@aanand asked for a use case:

In development, I want to bind mount $HOME/Projects/foo to /path/to/foo - so that I can have live updates to the app when I save the source on the host without restarting the container, for example.

My development container needs to be able to build foo which involves writing to /path/to/foo/bar in the container. If I don't setuid to the same ID as my user on the host, then my container can't write there, and can't build the project - unless uid=root.

As a workaround, I currently build as root, which sucks, and results in files that $USER on the host doesn't have ownership of in $HOME/Projects/foo, and causes all sorts of other problems for myself and colleagues.

In an ideal world, I would ensure that foo's build system didn't try to write to /path/to/foo, but to some other temporary place in the container which it had ownership of. But this does not seem easy to arrange. (It's go install which is writing those files because /path/to/foo is one of the things in $GOPATH, so it wants to put libraries in /path/to/foo/pkg).

(Finally, I'd like to instruct my colleagues to just run docker-compose up, rather than needing to teach them to do docker-compose up --user ... or something baroque like that).

With environment interpolation and user: in the yml, this is now supported.

We also have --user on docker-compose run

:+1:

Can you please give an example of how to use the environment interpolation?

The docs are here: https://github.com/docker/compose/blob/master/docs/yml.md#variable-substitution

The feature is in master, and will be in the 1.5.0 release.

web:
    user: ${USER}
    ...

How does this help? The USER env variable is the name of the current user, not the UID, which is what is needed for Docker.

web: user: ${USER}

is completely useless when the user-string is not known inside docker...

ERROR: for web Cannot start service web: linux spec user: unable to find user florian: no matching entries in passwd file

Yes, you have to create the user in the image first.

So what if you create a user in the image? That still doesn't help me set the UID and GID to match the ones in the host so I could mount the current project directory in the container and do, say, npm install or a myriad of other commands that produce files that I want the current user to own. Or maybe I just want to be able to access the current user's files in the container but give up root access.

Hi there,

Don't know if this questions still pops-up now, but here is the thing:

Why couldn't you set the UID / GID to match the ones in the host ?

For example, if I need to use composer in my image, then I just have to define a useradd line BEFORE it in the compose file. then telling my compose-file to use this user, with "USER ".

If you want to do things properly, use uids, and not names. So that you can even map host user to another username in VM keeping the same ids, which can be very useful sometimes (depending on what you want to do)

hello world, I was wondering if i could mount /etc/group and /etc/passwd as ro and than in my docker-compose.yml file

service-name:
    user:$USER:-0

has anyone tried that?

With environment interpolation and user: in the yml, this is now supported.

We also have --user on docker-compose run

Why only on the run command and not on up?
I'm asking because currently we implement docker-compose for a load-test with Jenkins pipelines. The pipeline is able to detect the user id of the "jenkins" user on the current node, but this does not have to be always the same. Also you really don't want to rebuild all docker images you are using for a CI system just to ensure a user named "jenkins". This is what we have left behind with Jenkins v1 and we don't want it back. ;)

If there is a way to use run for load tests without having the build job stuck in a never closing docker-compose thread (that's what I just got fixed with docker-compose up --exit-code-from <SERVICE>), I would be happy to hear from. Otherwise I would prefer having the --user flag on docker-compose up, too.

Also I agree with PandaaRun that using user ids is much more properly done than using user names.

Is it possible to specify an entrypoint that creates the correct username, uid and guid... then get that custom entrypoint (mounted in at runtime) to exec the default one. That way you don't have to rebuild maintained docker images.

Would the environment variables user: ${UID}:${GROUPS} always result in the correct uid:gid combo?

Was this page helpful?
0 / 5 - 0 ratings