在Jenkins和docker探员之间

在Jenkins和docker探员之间,docker,jenkins,jenkins-pipeline,Docker,Jenkins,Jenkins Pipeline,我们有几个Jenkins代理作为物理机器运行。 到目前为止,我在代理本身上运行了Jenkins管道,现在我尝试使用Jennis docker插件将构建和测试执行移动到docker容器中 下面您可以找到我们的Jenkins文件的简化版本,它使用gradle构建、测试和打包JavaSpring引导应用程序 node { stage('Preparation') { cleanWs() checkout scm notifyBitbucket()

我们有几个Jenkins代理作为物理机器运行。 到目前为止,我在代理本身上运行了Jenkins管道,现在我尝试使用Jennis docker插件将构建和测试执行移动到docker容器中

下面您可以找到我们的Jenkins文件的简化版本,它使用gradle构建、测试和打包JavaSpring引导应用程序

node {
    stage('Preparation') {
        cleanWs()
        checkout scm
        notifyBitbucket()
    }
}

pipeline {
    agent {
        docker {
            image "our-custom-registry.com/jenkins-build:latest"
            registryUrl 'https://our-custom-registry.com'
            registryCredentialsId '...'
            alwaysPull true
            args "-u jenkins -v /var/run/docker.sock:/var/run/docker.sock" // the pipeline itself required docker
        }
    }
    stages {
        stage('Build') {
            steps {
                sh './gradlew assemble classes testClasses'
            }
        }
        stage('Test') {
            parallel {
                stage('Unit Tests') {
                    when { expression { return build_params.ENABLE_UNITTEST } }
                    steps {
                        sh './gradlew test'
                        junit UNIT_TEST_RESULT_DIR
                    }
                }

                stage('Integration Tests') {
                    when { expression { return build_params.ENABLE_INTEGRATION } }
                    steps {
                        sh './gradlew integration'
                        junit INTEGRATION_TEST_RESULT_DIR
                    }
                }
            }
        }
        stage('Finalize') {
            stage('Docker Push') {
                when { expression { return build_params.ENABLE_DOCKER_PUSH } }
                steps {
                    sh './gradlew pushDockerImage'
                }
            }
        }
    }
    post {
        cleanup {
            cleanWs()
        }
        always {
            script {
                node {
                    currentBuild.result = currentBuild.result ?: 'SUCCESS'
                    notifyBitbucket()
                }
            }
        }
    }
}
下面是我用于构建映像的Dockerfile。正如您所见,我手动创建了一个Jenkins用户,并将添加到docker组(不幸的是,GID是998或999,具体取决于Jenkins代理)

然后,Jenkins执行以下命令

docker run -t -d -u 1001:1001 -u jenkins -v /var/run/docker.sock:/var/run/docker.sock  -w /var/jenkins/workspace/JOB_NAME -v /var/jenkins/workspace/JOB_NAME:/var/jenkins/workspace/JOB_NAME:rw,z -v /var/jenkins/workspace/JOB_NAME@tmp:/var/jenkins/workspace/JOB_NAME@tmp:rw,z -e ******** ... our-custom-registry.com/base/jenkins-build:latest cat
这条管道工作得很好。。。有时候! 然而,大多数情况下,一些文件会神秘地丢失

例如,my
build.gradle
包含多个其他文件。 在构建过程中的某个时刻,这些文件中的一个似乎丢失了

+ ./gradlew pushDockerImage

FAILURE: Build failed with an exception.

* Where:
Build file '/var/****/workspace/JOB_NAME/build.gradle' line: 35

* What went wrong:
A problem occurred evaluating root project 'foo'.
> Could not read script '/var/****/workspace/JOB_NAME/build/gradle/scripts/springboot-plugin.gradle' as it does not exist.
丢失的总是另一个文件

我在
/gradlew
之前开始运行
,以确保文件没有被实际删除

有人知道这里发生了什么吗

更新 忘了我说的关于docker的一切吧,这纯粹是Gradle和Jenkins的问题。 当我用普通的Jenkins代理替换docker代理时,同样的问题也会发生。 问题似乎是您不能在同一目录上并行运行多个gradle任务

+ ./gradlew pushDockerImage

FAILURE: Build failed with an exception.

* Where:
Build file '/var/****/workspace/JOB_NAME/build.gradle' line: 35

* What went wrong:
A problem occurred evaluating root project 'foo'.
> Could not read script '/var/****/workspace/JOB_NAME/build/gradle/scripts/springboot-plugin.gradle' as it does not exist.