我想在Docker容器中运行我的Maven构建。我不想在每次构建中上传所有的依赖项,所以我尝试挂载主机的本地Maven存储库,如码头与管道结合使用中所记录的那样
容器的缓存数据 ..。 管道支持添加传递给Docker的自定义参数,允许用户指定要挂载的自定义Docker卷,可用于在管道运行之间缓存代理上的数据。下面的示例将使用maven容器在管道运行之间缓存~/.m2,从而避免了重新下载管道后续运行的依赖关系的需要。 管道{代理{ docker { image‘maven:3-高寒’args '-v $HOME/.m2:/root/.m2‘}}阶段{阶段(’构建‘){步骤{ sh 'mvn -B’}
码
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v /home/jenkins/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}日志
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on jenkins-docker in /home/jenkins/workspace/Test/Docker Test@2
[Pipeline] {
[Pipeline] sh
+ docker inspect -f . maven:3-alpine
.
[Pipeline] withDockerContainer
jenkins-docker does not seem to be running inside a container
$ docker run -t -d -u 1000:1000 -v /home/jenkins/.m2:/root/.m2 -w "/home/jenkins/workspace/Test/Docker Test@2" -v "/home/jenkins/workspace/Test/Docker Test@2:/home/jenkins/workspace/Test/Docker Test@2:rw,z" -v "/home/jenkins/workspace/Test/Docker Test@2@tmp:/home/jenkins/workspace/Test/Docker Test@2@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 ******** maven:3-alpine cat
[...]
[DEBUG] Reading global settings from /usr/share/maven/conf/settings.xml
[DEBUG] Reading user settings from ?/.m2/settings.xml
[DEBUG] Reading global toolchains from /usr/share/maven/conf/toolchains.xml
[DEBUG] Reading user toolchains from ?/.m2/toolchains.xml
[DEBUG] Using local repository at /home/jenkins/workspace/Test/Docker Test@2/?/.m2/repository
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10.0 for /home/jenkins/workspace/Test/Docker Test@2/?/.m2/repository问题
在构建~/m2目录为空后,没有添加任何文件/目录。所有文件都是在/home/jenkins/workspace/Test/Docker Test@2/?/.m2下添加的(Test是文件夹的名称,Docker是对线的名称)。
问题是,这个目录仅用于这个特定管道,而不是其他管道,因此我无法与不同的管道/作业共享本地Maven存储库。
另外,我的settings.xml不被使用,因为它保存在~/m2下。
是否有使用Docker与不同管道共享本地Maven存储库和Maven设置的解决方案?
发布于 2019-03-11 22:57:05
您可以看到我的回答相关,但使用的是Gradle配置。
正如您所说的,在我的基本映像中,Jenkins使用用户1002运行Docker容器,并且没有定义用户。您必须配置Maven变量user.home,以便将依赖项放在那里。您可以通过将user.home包含在JAVA_OPTIONS中作为管道中的环境变量来实现。此外,还应包括MAVEN_CONFIG:
environment {
JAVA_TOOL_OPTIONS = '-Duser.home=/var/maven'
SETTINGS = credentials('your-secret-file')
}并创建一个卷来缓存依赖项:
docker {
image 'maven:3.3.9-jdk-8-alpine'
args '-v $HOME:/var/maven'
reuseNode true
}UPDATE:忘记告诉您您可以将settings.xml放在一个秘密文件中,以便进行使用“最少曝光原则”限制Jenkins管道中的凭据曝光。此外,我们正在配置个人凭据,这就是我们配置的方式,例如,每个用户都配置Nexus凭据。检查如何在凭据中上载机密文件的Jenkins文档:
sh 'mvn -s $SETTINGS -B clean verify'UPDATE2:我没有使用声明式管道,所以我的管道看起来如下:
withCredentials([
file(credentialsId: 'settings-xml', variable: 'SETTINGS')]) {
stage('Deploy') {
gitlabCommitStatus(name: 'Deploy') {
// Upload the Snapshot artefact
sh "mvn -s $SETTINGS clean verify"
}
}
}它似乎也可以在声明管道中使用,但我没有亲自测试它。
发布于 2019-03-11 16:14:39
我找到了一个解决办法,见当地的settings.xml没有被詹金斯探员接走
这个问题与jenkins用来运行容器的
-u uid:gid有关。正如您可能知道的,您正在运行的映像只创建了用户root,所以当jenkins传递自己的uid和gid时,用户没有条目,因此也就没有为其声明的$HOME。 如果只想独立于用户运行构建,可以使用以下代理: 代理{ docker { image‘maven:3-高寒’args '-v $HOME/.m2:/root/.m2:z -u root‘reuseNode true } 几个注意事项:
z一起使用的卷,正如我要用根用户构建的那样,我需要告诉docker,这个卷将在另一个容器之间共享,然后防止从我的jenkins容器(与用户jenkins而不是root用户一起运行)拒绝访问。日志
[DEBUG] Reading global settings from /usr/share/maven/conf/settings.xml
[DEBUG] Reading user settings from /root/.m2/settings.xml
[DEBUG] Reading global toolchains from /usr/share/maven/conf/toolchains.xml
[DEBUG] Reading user toolchains from /root/.m2/toolchains.xml
[DEBUG] Using local repository at /root/.m2/repository
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10.0 for /root/.m2/repository不幸的是,本地存储库/home/jenkins/.m2中的文件现在由用户root而不是用户jenkins拥有。这可能会引起其他问题。
发布于 2019-04-10 10:53:28
让Jenkins管道为Jenkins代理使用Docker容器和构建共享Maven本地存储库是很棘手的,因为有两个问题需要解决:共享本地存储库文件和确保文件具有可用权限。
我创建了一个Docker卷来保存共享文件:
docker volume create maven-cache然后告诉Jenkins将Docker卷挂载到适合每个代理的位置,让它为其--mount命令提供一个docker run选项。这使得码头的容量..。但是属于root,而不是运行代理的jenkins用户。
解决该权限问题的一个复杂问题是,Jenkins将使用Jenkins来docker run您的映像,并且您无法知道该UID将是什么。作为我在其他地方注意到了,您可以使用一些shell脚本魔术并运行命令来为您的jenkins映像设置jenkins用户名(如果需要的话,还有docker组名称)。
您可以通过将sudo添加到您的Docker映像并配置映像以允许jenkins用户在没有密码的情况下运行sudo命令来解决权限问题。然后,早期的Jenkins管道步骤可以使用sudo创建一个合适的目录,在共享挂载中保存本地存储库,并将该目录的所有者更改为jenkins。
最后,您可以设置一个Maven设置文件,供Jenkins代理使用,它告诉Maven使用共享的本地存储库。
我的Jenkinsfile是这样的
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
additionalBuildArgs '--build-arg JENKINSUID=`id -u jenkins` --build-arg JENKINSGID=`id -g jenkins` --build-arg DOCKERGID=`stat -c %g /var/run/docker.sock`'
args '-v /var/run/docker.sock:/var/run/docker.sock --mount type=volume,source=maven-cache,destination=/var/cache/maven -u jenkins:docker'
}
}
stages {
...
stage('Prepare') {
steps {
sh '[ -d /var/cache/maven/jenkins ] || sudo -n mkdir /var/cache/maven/jenkins'
sh 'sudo -n chown jenkins /var/cache/maven/jenkins'
...
sh 'mvn -B -s maven-jenkins-settings.xml clean'
}
}使用Maven的后续步骤还提到了mvn -B -s maven-jenkins-settings.xml ...。
我的Dockerfile.jenkinsAgent是这样的
FROM debian:stretch-backports
ARG JENKINSUID
ARG JENKINSGID
ARG DOCKERGID
# Add Docker CE
RUN apt-get -y update && \
apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
RUN apt-get -y update && \
apt-get -y install \
docker-ce \
docker-ce-cli \
containerd.io
# Add the build and test tools and libraries
RUN apt-get -y install \
... \
maven \
sudo \
...
# Set up the named users and groups
# Installing docker-ce will already have added a "docker" group,
# but perhaps with the wrong ID.
RUN groupadd -g ${JENKINSGID} jenkins
RUN groupmod -g ${DOCKERGID} docker
RUN useradd -c "Jenkins user" -g ${JENKINSGID} -G ${DOCKERGID} -M -N -u ${JENKINSUID} jenkins
# Allow the build agent to run root commands if it *really* wants to:
RUN echo "jenkins ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers(如果您的Jenkins管道本身没有运行Docker命令,您可以删除用于安装Docker的运行命令,但随后您将不得不groupadd docker组,而不是groupmod)
詹金斯代理(maven-jenkins-settings.xml)的Maven设置文件如下所示:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/var/cache/maven/jenkins</localRepository>
<interactiveMode>false</interactiveMode>
</settings>https://stackoverflow.com/questions/55104543
复制相似问题