您的位置:首页 > 运维架构 > Docker

jenkins git docker springboot项目的持续集成

2020-03-05 14:25 826 查看

学习如何使用jenkins git docker实现springboot项目的持续集成。
2019年12月3日10:21:50
环境: vmware14 Ubuntu 18 jdk1.8 docker的jenkins镜像 码云的git
之前一直在尝试花生壳的内网穿透,昨天看了一篇博客,内网主机ip地址原来是装花生壳客户端的主机内的内网ip,这里暂时映射本地8080,所以填127.0.0.1:8080(可见计算机网络学得有多差)
今天继续,之前应该是图省事,用jenkins的镜像,

docker inspect container_id | grep Mounts -A 20

这句用来查看容器的挂载目录

{
"Type": "bind",
"Source": "/home/jenkins",
"Destination": "/home/jenkins",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}

发现当初创建的时候只把/home/jenkins挂载到本地,jdk,maven没有

问题:已存在的容器怎么改挂载?

找到一篇问答,目前用不到,先不做

jenkins要想管理maven项目要装插件(好像叫 maven install…):安装失败解决方法
持续集成的大体思路参考下面博客:
实战docker+jenkins+git+registry构建持续集成环境
(registry:docker hub下载最新registry镜像 docker私有仓库)
在jenkins上点部署,jenkins从git垃代码,打包成maven包,发到tomcat容器上,tomcat容器重启

  1. git 在jenkins中添加ssh凭据,进入jenkins容器,ssh-keygen -t rsa -C "176XXXXXXXXX@163.com"生成ssh,

Your identification has been saved in /var/jenkins_home/.ssh/id_rsa.
Your public key has been saved in /var/jenkins_home/.ssh/id_rsa.pub.

生成在这里(之前没有把/var/jenkins_home挂载,容器重启可能会丢失证书,难受)。
jenkins ssh凭证
根据这个文章添加全局ssh凭证,但一直不对劲,SSH Username with private key,添加完不是ssh证书,
jenkins credentials & git ssh 认证
这一篇和我选的一样,(Passphrase 在生成ssh的时候默认设置了空)
差点掉坑里
刚说完发现自己进坑了,
凭据->系统->添加域 随便写一个名字 下一步,添加凭据->类型选SSH Username with private key(SSH用户名和私钥)
私钥!
私钥!
私钥!

cat id_rsa 查看私钥 ,复制
username可能是类似git提交的名字,不知道有啥用
private key 就是复制的秘钥,粘贴进去
passphrase 根据生成时,设置为空

接下来尝试新建任务,怎么连接tomcat容器也是个问题。
第二天了,新建任务填git地址,选昨天加的凭证,报了个403,

Error:403 No valid crumb was included in the request
取消勾选 防止跨站点请求伪造,感觉这里会留坑,crumb(面包屑)

jenkins在http请求头部中放置了一个名为.crumb的token。在使用了反向代理,并且在jenkins设置中勾选了“防止跨站点请求伪造(Prevent Cross Site Request Forgery exploits)”之后此token会被转发服务器apache/nginx认为是不合法头部而去掉。导致跳转失败。

jenkins镜像调用宿主机docker命令有问题,妈的,估计要改在宿主机装jenkins了

感觉讲得有道理,从了。宿主机安装jenkins的语句(官网这么写的)

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

安装报错:

ERROR: No Java executable found in current PATH: /bin:/usr/bin:/sbin:/usr/sbin

我的java不是装在这个目录,先执行echo $PATH 看看环境变量,建立软连接:

ln -s /usr/java/jdk1.8/bin/java /usr/bin/java(换成你自己的路径)

jenkins的默认端口是8080,如果8080被占用记得去改一下在/etc/default/jenkins这个文件改,改成8081或者其他的都可以
最后重启:service jenkins restart
之前听人说用apt-get install 有坑,调用 apt-get update会全部更新用apt-get的软件。
一如既往的安装,新建用户,登录之后是空白页面,解决方案:

浏览器访问:
http://127.0.0.1:8080/pluginManager/advanced
登陆之后将页面下拉到底部将升级站点的https改为http之后提交
重启jenkins
http://127.0.0.1:8080/restart

周天,反手再来一波,美滋滋。

这是刚创建账户之后安装插件,很多都失败了,这里报了很多错,搜索,安装,重启就好了。
要装maven
干! git用ssh,jenkins里git地址要用ssh的地址,
配置任务的pom地址在/var/lib/jenkins/workspace/任务名里(可能从git拉的代码就在这?)


因为用maven分了模块,推测jenkins这里配置的是modules的pom
第一次构建,报错:
应该是jdk的地址配错了,改好重部。

找不到service模块,因为我用的是modules的pom?改回来试一下

报错了


面向百度开发不好,但是真香。
接下来是一个很长的错误:

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /var/lib/jenkins/workspace/poker-server-test/SpringLearn-parent/SpringLearn-entity/src/main/java/org/SpringLearn/entity/holder/Hand.java:[3,36] package org.SpringLearn.common.enums does not exist
[ERROR] /var/lib/jenkins/workspace/poker-server-test/SpringLearn-parent/SpringLearn-entity/src/main/java/org/SpringLearn/entity/holder/CardHolder.java:[9,36] package org.SpringLearn.common.enums does not exist

entity 找不到common下的enum?想起来上面教的,屏蔽构建下游项目,勾选,重部

终于解决了,parent的pom里写了这一句:

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.XXXX.SpringbootApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>

pom文件中添加了“org.springframework.boot:spring-boot-maven-plugin”插件。在添加了该插件之后,当运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“java -jar”命令就可以直接运行。
可以在POM中,指定生成 的是Jar还是War jar 默认为jar
你还可以指定要执行的类,如果不指定的话,Spring会找有这个public static void main(String[] args)方法的类,当做可执行的类。当出现两个类含有main方法时,会报错。

com.XXXX.SpringbootApplication 这个类是modules的启动类,common在modules的上游,打包出错,entity就找不到common了,但是本地不会报错,猜测本地启动是从modules模块开始,所以build应该写在modules里。项目结构:

参考公司的pom写法:

<packaging>war</packaging>
<build>
<finalName>ROOT</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>

maven-surefire-plugin
ClassLoader相关配置
解决classpath长度超过命令行运行的最大参数长度问题。
方法有两个,各有优缺点:
一是使用独立的类加载器,在其中加载classpath内容。
二是使用一个只有META-INF/MANIFEST.MF的jar文件(如booter.jar),在manifest.mf文件中配置classpath。然后以 java -classpath booter.jar MyApp的方式运行。
配置方法
useSystemClassLoader为fasle, 使用独立的类加载器。
useSystemClassLoader为true并且useManifestOnlyJar为true时 ,使用manifest-only JAR
useSystemClassLoader为true并且useManifestOnlyJar为false时,使用最原始的java classpath

结果本地跑不了,不该把.class删除,sourcetree配置了不跟踪.class文件但是不好使,废了好大劲。

成功了。


接下来就要找到war,发送到tomcat上,公司的jenkins用的是shell脚本部署到远程的tomcat容器上,学习一下shell。
现场时一下博客里的方法

先到tomcat里改~/conf/tomcat-users.xml,加管理员用户,所以tomcat容器的conf文件夹可以考虑挂载到宿主机

docker run --name tomcat_dev -p 8080:8080 -v $PWD/conf:/usr/local/tomcat/conf -d tomcat

挂载后由于当前conf文件夹下是空的,导致tomcat启动失败,所以我再开一个容器并将其中的conf文件拷贝到上一个tomcat挂载到宿主机的conf中

docker run --name tomcat -d tomcat
docker cp 4eb5d123f31c:/usr/local/tomcat/conf $PWD
//第一个参数是CONTAINER ID 第二个是容器中文件的位置 第三个是宿主记得位置

配置tomcat管理员
这里介绍还要改一个配置,淦!懒得再挂载了,直接进去装vim然后改配置。
改好在浏览器登录tomcat果然生效了。
回头配置jenkins

点击构建,报错:

[XXXX-server-test] $ /bin/sh -xe /tmp/jenkins1908085146001650202.sh
ERROR: Step ‘Deploy war/ear to a container’ aborted due to exception:
java.lang.InterruptedException: [DeployPublisher][WARN] No wars found. Deploy aborted. %nat hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:107)
at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:79)
at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:741)
at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.post2(MavenModuleSetBuild.java:1074)
at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
at hudson.model.Run.execute(Run.java:1841)
at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:543)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
Finished: FAILURE

找不到war包?博客里说

WAR/EAR files):是war包的相对路径(相对于工作区路径,即在工作区中war包的相对路径.)如我的maven执行完成之后会在工作区的target目录下生成项目.war,所以这里我的路径就写target\项目.war.

看完还是懵逼,不知道到底是哪里,所以在WAR/EAR files里写$PWD

构建之后就可以看到路径了($PWD表示当前路径):

原来如此。。。。。继续修改路径,构建,又报错,

java.lang.InterruptedException: [DeployPublisher][WARN] No wars found. Deploy aborted. %n

??还找不到?? 最后在控制台输出中找到了关键:

这么明显的信息就放在开头。。。。。。。
我也查到一种万金油的写法:

**/*.war

这样甭管是谁全部算上,当然如果有其他war那就乱套了,重新构建,报错:

Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: http://127.0.0.1:8080/manager/text/list
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1919)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:577)
... 21 more                                                   //重点在这里,意思是这个用户没有权限访问/manager/text/list
org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The username you provided is not allowed to use the text-based Tomcat Manager (error 403)
at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:710)
at org.codehaus.cargo.container.tomcat.internal.TomcatManager.list(TomcatManager.java:882)
at org.codehaus.cargo.container.tomcat.internal.TomcatManager.getStatus(TomcatManager.java:895)
at

完善一下tomcat用户权限配置:

<role rolename="manager-gui" />
<role rolename="manager-script" />
<role rolename="manager-status" />
<user username="deploy" password="tomcat" roles="manager-gui,manager-script,manager-status" />

构建成功!!!!!

访问一下tomcat,成功啦!!( ̄▽ ̄)/

  • 点赞
  • 收藏
  • 分享
  • 文章举报
weixin_41653901 发布了2 篇原创文章 · 获赞 0 · 访问量 56 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: