这是我的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
来运行新容器?
信息:该问题似乎与声明性管道无关,因为我只是尝试使用命令式样式,并且还获得了与詹金斯容器相同的pwd
:https://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
答案 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
的注释-如果我没记错的话,这似乎是由于打字错误造成的。