• Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • docker-workflow-plugin
    • None
    • Jenkins Core 2.73

      When running a build inside a docker container, some commands don't work because they rely on the user being properly set. For example, ssh doesn't work with the following error:

       

      No user exists for uid 150.

       

      I think this could be solved by append to passwd on container startup, something like this (untested, for proof of concept):

      if [ "$(id -u)" != "0" ]; then

          echo "jenkins:x:$(id -u):$(id -g):Jenkins:${HOME}:/sbin/nologin" >> /etc/passwd

      fi

          [JENKINS-47026] User not completely set in docker containers

          Waldek M added a comment -

          I took the liberty to link issue JENKINS-49416 which is also a consequence of how is spinning Docker containers with an arbitrary user / group / entry point script.

          Waldek M added a comment - I took the liberty to link issue JENKINS-49416 which is also a consequence of how is spinning Docker containers with an arbitrary user / group / entry point script.

          Taras Bondarchuk added a comment - - edited

          Since I'm building agent from Dockerfile anyway, I've fixed this by:

           

          agent {
             dockerfile {
                additionalBuildArgs '--build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g)'
             }
          }
          

          and in Dockerfile:

           

          ARG USER_ID=1000
          ARG GROUP_ID=1000
          RUN groupadd -g $GROUP_ID user && \
              useradd -u $USER_ID -s /bin/sh -g user user
          

          Taras Bondarchuk added a comment - - edited Since I'm building agent from Dockerfile anyway, I've fixed this by:   agent { dockerfile { additionalBuildArgs '--build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g)' } } and in Dockerfile:   ARG USER_ID=1000 ARG GROUP_ID=1000 RUN groupadd -g $GROUP_ID user && \ useradd -u $USER_ID -s /bin/sh -g user user

          Waldek M added a comment - - edited

          Thanks for sharing the workaround, aliusmiles!

           

          Interestingly, passing such arguments to the prebuilt image with a `docker` closure did not work for me

           

          agent {
              docker {
                image 'foo'
                args '--env USER_ID=$(id -u){{ --env GROUP_ID=$(id -g)'
              }   
          }

          The values passed were literally "$(id -u)" (not interpreted.

          I'll give it a go and see.

          Waldek M added a comment - - edited Thanks for sharing the workaround, aliusmiles !   Interestingly, passing such arguments to the prebuilt image with a `docker` closure did not work for me   agent {     docker {       image 'foo'       args '--env USER_ID=$(id -u){{ --env GROUP_ID=$(id -g)'     }    } The values passed were literally " $(id -u) " (not interpreted. I'll give it a go and see.

          Waldek M added a comment -

          Just for the record: Dockerfile workaround worked fine. Thank you!

          Waldek M added a comment - Just for the record: Dockerfile workaround worked fine. Thank you!

          Michael Slattery added a comment - - edited

          This workaround worked for me without having to do the Dockerfile workaround.

          environment {
              JAVA_OPTS="-Duser.home=${JENKINS_HOME}"
              MAVEN_OPTS="${JAVA_OPTS}"
              MAVEN_CONFIG="${JENKINS_HOME}/.m2"  // docker/maven specific.
          }
          agent {
              docker {
                  image 'buildtool'
                  args "-e HOME=${JENKINS_HOME}"
              }
          }
          

          I prefer this solution as it universally works with all containers (so far) and we use a few off-the-shelf images that I'd rather not heavily modify.

          I believe most tools will work, including maven, gradle, pip, npm, git, etc.

          Michael Slattery added a comment - - edited This workaround worked for me without having to do the Dockerfile workaround. environment { JAVA_OPTS= "-Duser.home=${JENKINS_HOME}" MAVEN_OPTS= "${JAVA_OPTS}" MAVEN_CONFIG= "${JENKINS_HOME}/.m2" // docker/maven specific. } agent { docker { image 'buildtool' args "-e HOME=${JENKINS_HOME}" } } I prefer this solution as it universally works with all containers (so far) and we use a few off-the-shelf images that I'd rather not heavily modify. I believe most tools will work, including maven, gradle, pip, npm, git, etc.

          One way you can solve this is by mounting the /etc/passwd file from the Docker host into the container within the docker block in the Jenkins Pipeline configuration.

          args '-v /etc/passwd:/etc/passwd:ro'

          Daniel Sorensen added a comment - One way you can solve this is by mounting the /etc/passwd file from the Docker host into the container within the docker block in the Jenkins Pipeline configuration. args '-v /etc/passwd:/etc/passwd:ro'

          Waldek M added a comment -

          Depends on your setup; it won't work if you're using LDAP or any other external authentication service.

          Waldek M added a comment - Depends on your setup; it won't work if you're using LDAP or any other external authentication service.

          a b added a comment -

          mslattery If I'm understanding your suggestion correctly I believe this just sets the home / working dir for the particular tool to the mapped Jenkins workspace?

          If so that might work on a tool by tool basis in some cases but I don't believe this would solve the root issue for programs like SSH which rely on proper entries in /etc/passwd at a minimum.

          a b added a comment - mslattery If I'm understanding your suggestion correctly I believe this just sets the home / working dir for the particular tool to the mapped Jenkins workspace? If so that might work on a tool by tool basis in some cases but I don't believe this would solve the root issue for programs like SSH which rely on proper entries in /etc/passwd at a minimum.

          a b added a comment -

          We are running from a pre-built image right now for various reasons and ended up doing the groupadd / useradd method but have had to hard-code the details in our base Dockerfiles / layers before build. Very unfortunate workaround. Hopefully this gets fixed at some point.

          a b added a comment - We are running from a pre-built image right now for various reasons and ended up doing the groupadd / useradd method but have had to hard-code the details in our base Dockerfiles / layers before build. Very unfortunate workaround. Hopefully this gets fixed at some point.

          a b added a comment -

          weakcamel did you ever get the following method to work somehow? I am in the same position and we aren't able to use dockerfiles right now.
          agent {
              docker {
                image 'foo'      args '--env USER_ID=$(id -u){{ --env GROUP_ID=$(id -g)'    }   
          }

          a b added a comment - weakcamel  did you ever get the following method to work somehow? I am in the same position and we aren't able to use dockerfiles right now. agent {     docker {       image 'foo'      args '--env USER_ID=$(id -u){{ --env GROUP_ID=$(id -g)'    }    }

            Unassigned Unassigned
            edahlseng Eric Dahlseng
            Votes:
            6 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated: