Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-49076

Cannot set custom PATH inside docker container

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • docker-workflow-plugin
    • None
    • Jenkins 2.89.3
      docker-workflow 1.14

      I'm trying to set a custom PATH in a docker.image('...').inside block.

      For example, I would like to be able to do something like this:

      node('docker') {
          docker.image('some-build-image').inside {
              sh 'echo $PATH'
              withEnv(['PATH+MAVEN=/opt/maven-3.3.3/bin']) {
                  sh 'echo $PATH'
                  sh 'mvn --version'
              }
          }
      }
      

      But the PATH environment variable inside the docker image does not get updated - the two echo statements produce exactly the same output, and the Maven command fails with the following error: "mvn: command not found"

      I see that as a result of #JENKINS-43590, the PATH env var is no longer passed from the host to the docker container (which seems sensible, as the environments can be different), but I feel it should still possible to manipulate the PATH variable inside the docker container somehow, e.g by using withEnv. Even a workaround like running the shell step sh 'export PATH=$PATH:/opt/maven-3.3.3/bin' does not have the required outcome.

          [JENKINS-49076] Cannot set custom PATH inside docker container

          Robin Smith created issue -

          Kieran Webber added a comment -

          Just ran into this issue using withEnv in a docker container. Works for everything but PATH currently.

          Kieran Webber added a comment - Just ran into this issue using withEnv in a docker container. Works for everything but PATH currently.
          Allan BURDAJEWICZ made changes -
          Link New: This issue relates to JENKINS-43590 [ JENKINS-43590 ]

          Steven Clark added a comment - - edited

          I believe this may be the root cause as well with the failures I'm seeing within a declarative pipeline. Running this PATH from the env command is the normal value and not the value within my pipeline. This only seems to break when the agent is a docker

          pipeline {
              agent {
                  docker {
                      image 'debian:stretch'
                  }
              }
              
              environment {
                  PATH = "/opt/test/bin:/usr/bin/:/bin"
              }
              
              stages {
                  stage('Example') {
                      steps {
                          sh 'env'
                      }
                  }
              }
          }

          Steven Clark added a comment - - edited I believe this may be the root cause as well with the failures I'm seeing within a declarative pipeline. Running this PATH from the env command is the normal value and not the value within my pipeline. This only seems to break when the agent is a docker pipeline {     agent {         docker {             image 'debian:stretch'         }     }          environment {         PATH = "/opt/test/bin:/usr/bin/:/bin"     }          stages {         stage( 'Example' ) {             steps {                 sh 'env'             }         }     } }

          Rong Shen added a comment - - edited

          I'm seeing same issue here.

          It is definitely necessary to have a way to set PATH variable inside docker container. We have a PATH environment variable is dynamic changing with Jenkins workspace path that can only set through code.

          Is there a workaround for this issue?

          Rong Shen added a comment - - edited I'm seeing same issue here. It is definitely necessary to have a way to set PATH variable inside docker container. We have a PATH environment variable is dynamic changing with Jenkins workspace path that can only set through code. Is there a workaround for this issue?

          I did something like this as workaround:

              // Get the full PATH variable from a started container.
              def pathInContainer
              docker.image(DockerImage).inside() {
                pathInContainer = steps.sh(script: 'echo $PATH', returnStdout: true).trim()
                parameters += "-e PATH=${pathInContainer}:/misc/AddExtraPath "
              }    
          
              docker.image(DockerImage)
                          .inside(parameters) {
                runA()
                runB()
              }
           

          It extracts the PATH from a started container, then stops the container, and starts a new one with the extra PATH environment variable (which I extended with the things required by us).

          Paul Theunissen added a comment - I did something like this as workaround: // Get the full PATH variable from a started container. def pathInContainer docker.image(DockerImage).inside() { pathInContainer = steps.sh(script: 'echo $PATH' , returnStdout: true ).trim() parameters += "-e PATH=${pathInContainer}:/misc/AddExtraPath " } docker.image(DockerImage) .inside(parameters) { runA() runB() } It extracts the PATH from a started container, then stops the container, and starts a new one with the extra PATH environment variable (which I extended with the things required by us).

          Rong Shen added a comment -

          Thank you theuno! Let me have a try

          Rong Shen added a comment - Thank you theuno ! Let me have a try
          Matt Evans made changes -
          Link New: This issue is duplicated by JENKINS-53025 [ JENKINS-53025 ]

          Nenad Miksa added a comment -

          Any update on this issue? The workaround by theuno works, but its very ugly and inpractical for some use cases.

           

          Nenad Miksa added a comment - Any update on this issue? The workaround by theuno works, but its very ugly and inpractical for some use cases.  

          Another workaround is to run commands in a modified environment:

          pipeline {
              agent {
                  docker {
                      image 'debian'
                  }
              }
              environment {
                  PATH = '/some/dir'
              }
              stages {
                  stage('Test') {
                      steps {
                          sh "env PATH=$PATH:\$PATH"
                      }
                  }
              }
          }
          

          The resulting PATH variable contains /some/dir prepended to the PATH value defined inside the container (observe double quotes in the steps directive).

          I fully agree with the others, that the option to manipulate the PATH variable inside a container is a must-have. Note, that this feature has nothing to do with setting the PATH inside a container to the value this variable has outside of it, i.e. on the Jenkins node, which would be obviously wrong in most cases.

          Lukasz Walewski added a comment - Another workaround is to run commands in a modified environment: pipeline { agent { docker { image 'debian' } } environment { PATH = '/some/dir' } stages { stage( 'Test' ) { steps { sh "env PATH=$PATH:\$PATH" } } } } The resulting PATH variable contains /some/dir prepended to the PATH value defined inside the container (observe double quotes in the steps directive). I fully agree with the others, that the option to manipulate the PATH variable inside a container is a must-have. Note, that this feature has nothing to do with setting the PATH inside a container to the value this variable has outside of it, i.e. on the Jenkins node, which would be obviously wrong in most cases.

            Unassigned Unassigned
            robin_smith Robin Smith
            Votes:
            21 Vote for this issue
            Watchers:
            27 Start watching this issue

              Created:
              Updated: