docker
docker copied to clipboard
uid and gid as ENV variables
Issues and Contributing
Is it possible to add uid and gid as ENV variables to have an ability to change it during the docker run? It would be very helpful to run container on the machine with another uid/gid for the jenkins user than 1000/1000 and when mount should be used.
+1 not sure why its hardcoded to run under uid 1000..
You don't need an ENV variable to change the user. That can be done at run time with flags like:
docker run --user 1001
UIDs tend to be set in the Dockerfile to ensure that by default the container doesn't run as root. You can always map the UID/GID of the container at run time to another ID.
If you'd like to dive more into it a good reference is here: https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf
By using --user option, we can change the uid to run the container. However, if the uid isn't included in the /etc/passwd, which is the case in most cases, we get errors including "I have no name!" described in the above Medium article. I understand we can't resolve this issue even if we can set uid/gid using ENV.
The issue here for me is that 1000 is the uid Linux system assigns first. The uid is already taken by a real user and if we attach a volume for the jenkins_home, we should make it writable to the user uid=1000 in the host system.
Do you think it is possible to change the uid used in the container to a more uncommon one, such ash 10000 or so? Then, I can create a user/group for jenkins in the host system with the ids.
You don't need an ENV variable to change the user. That can be done at run time with flags like:
Yes "I" need it. Running it in synology under docker DOES NOT work with flags. Every other docker image I used until I tried to use jenkins uses env variables. Don't see any issue doing that then.
@Subtixx did you solve this?
No, just resorted to using a VM instead.. Shame that they don't care.
I think we could take a PR for this, it would require a test, and also needs a change to the script that runs on startup to crown the files to the new owner of required
FYI @dduportal
Setting a user with a fixed UID inside an image is a good practise to ensure that there is NO dependency with the underlying host: it allows the image to have deterministic behavior ("immutable image" pattern).
It is recommended to use Docker named volumes to ensure that the UID is not an issue, instead of sharing a directory on the host (it is the same thing under the hood, but with named volume, Docker managed the UID, GID, mask and paths for you):
$ docker volume create jenkins_data
$ docker run --detach --name=jenkins --volume jenkins_data:/var/jenkins-home:rw <...> jenkins/jenkins:lts
# Access data from another temporary container when required. Write to current directory
$ docker run --name=backup-jenkins --rm --volume jenkins_data:/data:ro alpine tar xzf - /data > ./jenkins_backup.tgz
=> If you cannot use named volume, can you describe the issue you have with it please?
You can also rebuild you own flavor of the image as per https://github.com/jenkinsci/docker/issues/1017#issuecomment-882088022.
Creating the user on runtime (instead of buildtime) could be done but at the cost of additional complexity that need to be written and tested. It is not on the priorities, but anyone interested in contributing can.
Please keep in mind that:
- The whole entrypoint script will have to be working with the plugins+ref creation into volume dir
- The "create at runtime" requires running chmod/chown on each container startup. This can be slow if there are a lot of jobs in Jenkins, or if the underlying filesystem is slow
- User Namespacing must keep working with the "runtime user creation" https://docs.docker.com/engine/security/userns-remap/
Thanks for all that info @dduportal, also fyi @MarkEWaite
It sounds like the above should be documented as the recommended way? as there's a number of issues where people have hit this
That is a really good point. I initially assumed that the existing documentation was enough (ref. 2nd part of https://github.com/jenkinsci/docker#usage), but in fact it could be greatly improved since end users are still facing issues: it means there is room for improvement. Any help on this is welcome, as I'm not a native English speaker and I fear that I might not write correctly.
- The "create at runtime" requires running chmod/chown on each container startup. This can be slow if there are a lot of jobs in Jenkins, or if the underlying filesystem is slow
chmod/chown could be run if uid is the different that set by parameter. it will be fast in most cases
I doubt it will be that fast, once you get a lot of jobs it will take a long time.
Is there a reason that you don't want to use named volumes?
As I understand, named volumes will produce files with ownership of user from container (uid/gid). For example, if I have jenkins user id 1000 in container, everything that was created by jenkins will have owner 1000 on the host machine. As the result host user with id 1000 can corrupt files. Am I wrong?
@ikutergin yes, but inside the volume managed by docker (that is stored in /var/lib/docker/volumes/<volume id>/_data). Please note that you have to enable https://docs.docker.com/engine/security/userns-remap/ if the UID 1000 should be used on your host machine: it will allow to map the UID 1000 of the container to another UID on the host machine.
@ikutergin what is the use case you have to would be incompatible with the named volume?
@ikutergin yes, but inside the volume managed by docker (that is stored in
/var/lib/docker/volumes/<volume id>/_data). Please note that you have to enable https://docs.docker.com/engine/security/userns-remap/ if the UID1000should be used on your host machine: it will allow to map the UID1000of the container to another UID on the host machine.
As I understand, userns-remap configured for whole system. If I have multiple independent containers on the host, all of them will use this option.
Yes, but without any information on your use case it is only a hard guess. Can you describe what you want to achieve to help us understand please ?
Le 20 juil. 2021 à 13:23, ikutergin @.***> a écrit :
@ikutergin yes, but inside the volume managed by docker (that is stored in /var/lib/docker/volumes/
/_data). Please note that you have to enable https://docs.docker.com/engine/security/userns-remap/ if the UID 1000 should be used on your host machine: it will allow to map the UID 1000 of the container to another UID on the host machine. As I understand, userns-remap configured for whole system. If I have multiple independent containers on the host, all of them will use this option.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
You don't need an ENV variable to change the user. That can be done at run time with flags like:
Yes "I" need it. Running it in synology under docker DOES NOT work with flags. Every other docker image I used until I tried to use jenkins uses env variables. Don't see any issue doing that then.
I can only repeat myself.
This suggests you should be able to use named volumes with synology? https://community.synology.com/enu/forum/1/post/133301
You don't need an ENV variable to change the user. That can be done at run time with flags like:
Yes "I" need it. Running it in synology under docker DOES NOT work with flags. Every other docker image I used until I tried to use jenkins uses env variables. Don't see any issue doing that then.
I can only repeat myself.
+1 to this issue. uid/gid needs to match that of the Jenkins container and uid/gid 1000 is very common.
+1 here as well. My org has centralized auth and 1000:1000 belongs to somebody. Because of the centralized auth, /etc/subuid and /etc/subgid already map users and are not available for docker userns-remap. I had to fork the repo and hack the Dockerfile for uid/gid, so I'm no longer pulling the official image. What bothers me is that there appears to be no way to pass in build-args for uid and gid via the Makefile. I wouldn't have to fork (and thereby track) the repo if there were even a way to do something that simple. Not only, but building LATEST_LTS doesn't actually build the same image as jenkins/jenkins:lts-jdk11. It builds 2.303 instead of 2.303.2, leading to lots of deprecation messages upon startup. So I have to specify JENKINS_VERSION and JENKINS_SHA for the build to boot. This is a lot to go through to keep asking what we want to achieve. We want to achieve a secure deployment. And for me that is also without having to hack a fork. I can make the sacrifice of building from source if there's a way to pass in uid and gid to make without hacking. An even more elegant solution would be to use the official images and pass in uid and gid at runtime. But that might take considerable rewiring. So I'd be happy just to be able to build from source and pass uid and gid to make if there were a way to do that besides hacking, even if that is less elegant that specifying at runtime.
I can make the sacrifice of building from source if there's a way to pass in uid and gid to make without hacking
Hello @cbcunc , for what it's worth it, you can avoid hacking and specify the uid/gid through the "docker-bake.hcl" manifest file.
This "manifest" is used by the docker buildx bake command to get the correct build settings for a given image (path to dockerfile, build args, names, etc.).
The Makefile is only a remnant from the past, kept for executing commands: it should not be used to persist informations.
You have an example of build arg already there: https://github.com/jenkinsci/docker/blob/master/docker-bake.hcl#L177-L182 which sets the build-arg from the value of the respective environment variables. You could add another with your expected uid/gid on the image you want to build, because it's exposed through build-args: https://github.com/jenkinsci/docker/blob/master/11/debian/bullseye/hotspot/Dockerfile#L34-L41 .
Would it help you?
@dduportal, I had done something like this before your reply:
https://github.com/cznethub/jenkins-docker/commit/ffab6aa20f1bac3633ba132da920ba0ae552ec9a
and then ran:
export JENKINS_SHA=c4b8532e25a33001a3d8883d3cd87a664953ace239b486839b683065817d29cf
export JENKINS_VERSION=2.303.2
export LATEST_LTS=true
export JENKINS_REPO=myproject-jenkins
export JENKINS_USER=myproject-user
export JENKINS_GROUP=myproject-group
export JENKINS_UID=$(id -u ${JENKINS_USER})
export JENKINS_GID=$(getent group ${JENKINS_GROUP} | cut -d: -f3)
make build-debian_jdk11
to get it to work. Is that like what you are suggesting? I was thinking of generalizing this to the other *nix platforms, documenting it, and contributing back if you think that would be worthwhile.
For those who need a different uid/gid, which one should it be?
If there would be a specific combination, we could try to file a PR which adds another build variant. But I guess we all need different combinations. e.g. containers running root-less on Openshift would need a docker build with uid=1001 and gid=0.
PR #1342 adds a build with uid:gid being 1001:0
build it with e.g.:
export JENKINS_VERSION=2.332.3
export JENKINS_SHA=$(curl -sL "https://get.jenkins.io/war-stable/${VERSION}/jenkins.war.sha256" | cut -d' ' -f1)
make build-rhel_ocp_ubi8_jdk11