Jenkins:dockerfile代理命令未在容器中运行

时间:2018-12-27 19:47:23

标签: docker jenkins

这是我的Jenkins文件:

pipeline {
    agent {
        dockerfile true
    }

    stages {
        stage('Run tests') {
            steps {
                sh 'pwd'
                sh 'vendor/bin/phpunit'
            }
        }
    }
}

我正在运行Jenkins,尽管我能够成功构建映像,但是“运行测试”是在主机中新容器的外部 中运行。这个不好;我希望命令从借助dockerfile代理构建的新容器中运行。

我知道shell命令在主机中运行,因为我已经尝试使用sh pwd到的/var/jenkins_home/workspace/youtube-delete-tracker_jenkins进行调试。

这是Jenkins作业在控制台中输出的结尾:

Step 18/18 : RUN chmod a+rw database/
 ---> Using cache
 ---> 0fedd44ea512
Successfully built 0fedd44ea512
Successfully tagged e74bf5ee4aa59afc2c4524c57a81bdff8a341140:latest
[Pipeline] dockerFingerprintFrom
[Pipeline] }
[Pipeline] // stage
[Pipeline] sh
+ docker inspect -f . e74bf5ee4aa59afc2c4524c57a81bdff8a341140
.
[Pipeline] withDockerContainer
Jenkins does not seem to be running inside a container
$ docker run -t -d -u 112:116 -w /var/jenkins_home/workspace/ube-delete-tracker_stackoverflow -v /var/jenkins_home/workspace/ube-delete-tracker_stackoverflow:/var/jenkins_home/workspace/ube-delete-tracker_stackoverflow:rw,z -v /var/jenkins_home/workspace/ube-delete-tracker_stackoverflow@tmp:/var/jenkins_home/workspace/ube-delete-tracker_stackoverflow@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** e74bf5ee4aa59afc2c4524c57a81bdff8a341140 cat
$ docker top 64bbdf257492046835d7cfc17413fb2d78c858234aa5936d7427721f0038742b -eo pid,comm
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Run tests)
[Pipeline] sh
+ pwd
/var/jenkins_home/workspace/ube-delete-tracker_stackoverflow
[Pipeline] sh
+ vendor/bin/phpunit
/var/jenkins_home/workspace/ube-delete-tracker_stackoverflow@tmp/durable-4049973d/script.sh: 1: /var/jenkins_home/workspace/ube-delete-tracker_stackoverflow@tmp/durable-4049973d/script.sh: vendor/bin/phpunit: not found
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 64bbdf257492046835d7cfc17413fb2d78c858234aa5936d7427721f0038742b
$ docker rm -f 64bbdf257492046835d7cfc17413fb2d78c858234aa5936d7427721f0038742b
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline

如您所见,pwd为我提供了主机(Jenkins作业文件夹)上的路径,并且没有找到vendor/bin/phpunit(应该在容器中,因为软件包管理器已成功按照我未包含的docker build输出来构建它。)

那么如何从容器中运行sh命令?或者,如何获取dockerfile代理生成的图像标签名称,以便可以从新容器外部手动执行docker run来运行新容器?

信息:该问题似乎与声明性管道无关,因为我只是尝试使用命令式样式,并且还获得了与詹金斯容器相同的pwdhttps://github.com/amcsi/youtube-delete-tracker/blob/4bf584a358c9fecf02bc239469355a2db5816905/Jenkinsfile.groovy#L6

信息2:起初我以为这是一个Jenkins-in-Docker问题,我这样写了我的问题...但是事实证明,如果我在主机上而不是内部运行Jenkins,我也会遇到同样的问题一个容器。

信息3:版本...

Jenkins ver. 2.150.1
Docker version 18.09.0, build 4d60db4
Ubuntu 18.04.1 LTS

1 个答案:

答案 0 :(得分:2)

编辑:

Jenkins将其本地工作区安装到docker容器中,并自动将其放入cd。因此,您在Dockerfile中设置的WORKDIR被覆盖。在控制台输出中,docker run命令显示了这一事实:

docker run -t -d -u 112:116 -w /var/jenkins_home/workspace/ube-delete-tracker_stackoverflow -v /var/jenkins_home/workspace/ube-delete-tracker_stackoverflow:/var/jenkins_home/workspace/ube-delete-tracker_stackoverflow:rw,z

从docker run手册页(man docker run):

   -w, --workdir=""
      Working directory inside the container
     

在容器中运行二进制文件的默认工作目录是根目录(/)。开发人员可以设置其他   默认为          Dockerfile WORKDIR指令。操作员可以使用-w选项覆盖工作目录。

   -v|--volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]]
      Create a bind mount. 
     

如果您指定-v / HOST-DIR:/ CONTAINER-DIR,Docker   将主机中的/ HOST-DIR挂载绑定到Docker中的/ CONTAINER-DIR   容器。如果省略“ HOST-DIR”,则Docker将自动创建新的   主机上的音量。选项是用逗号分隔的列表,可以是:

因此,在执行上述命令之前,您需要先手动将CD放入自己的$ WORKDIR中。顺便说一句,您可能还想创建一个从jenkins卷装载目录到您自己的$ WORKDIR的符号链接(ln -s)。这使您可以通过Jenkins UI等浏览工作区。

最后,为澄清起见,如果您在顶部指定docker agent,Jenkins将在Docker容器中运行其所有构建阶段。


旧答案:

如果您在顶部指定Docker代理,Jenkins将在Docker容器内运行其所有构建阶段。您可以使用环境变量来验证构建在哪个执行程序和从属程序上运行。

因此,首先找出一个特定于您的从属的环境变量。为此,我使用了NODE_NAME env var。您可以通过http://localhost:8080/env-vars.html找出Jenkins实例中所有可用的环境变量(替换主机名以匹配您的实例)。

...
stages {
    stage('Run tests') {
        steps {
            echo "I'm executing in node: ${env.NODE_NAME}"
            sh 'vendor /bin/phpunit'
        }
    }
}
...

关于vendor/bin/phpunit was not found的注释-如果我没记错的话,这似乎是由于打字错误造成的。