{% if theme.baidu_site_verification %} {% endif %}

Jenkins+GitLab自动化部署SpringBoot项目(2024版)


前言

        在我上个博客,用的SpringBoot整合项目,前后端不分离。项目最初有很多要改动的地方,每次改动,都要重新部署打包,传到云服务,再用命令启动项目。这样重复的工作很枯燥单调,一个小博客如此,何况企业级的项目,因此这篇聊到的技术就是解决这样的问题。还有我当时在北京某银行外包,银行的项目都是大型项目,开发流程也很专业。实际工作中他们就用到了自动化部署。这个工作主要是运维负责,对于一个开发来说,虽然主要工作是写代码,但我对这样的提高工作效率的工具还是有一些兴趣,所以学习学习。

手动构建

 毕竟是学习,所以把一些细节该简化就简化。先把握整体思路,从简到难。我们先实现的需求是:从本地提交代码到gitlab,然后手动在Jenkins点构建,项目重新发布成功。

一、准备SpringBoot项目

  在本地IDEA创建一个SpringBoot项目,这个项目是目的是能反馈最直观效果的。所以可以搞一个很精简版的,连数据库都不用连接,这里给出我自己创建好的,gitee地址。你可以直接下载拿来使用。

我在创建这个的时候碰到的主要小问题如下:

SpringBoot打的jar包,在执行java -jar 提示no main manifest attribute

原因:pom.xml没有引入以下配置,没有的话源码工程内添加后,重新打jar包。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

还有一个问题是我这个项目不连数据库,但在启动的时候SpringBoot会扫描数据库配置,你没有配置它默认会识别并报错,所以我这边在SpringBoot启动类后面加如下注解,把数据库配置检测排除。

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})

二、准备好环境

  所需软件GitLab(v16.7.0),Docker,Jenkins(2.442),Maven,jdk11,VMware 等等,所有环境都在本地虚拟机上运行,本机电脑内存至少16G,两台虚拟机,一台负责启动GitLab,另一台负责Jenkins和SpringBoot项目。

  GitLab用Docker启动,Jenkins在官网下载war包,用java -jar启动,现在Jenkins官方对jdk版本的要求是至少是jdk11及以上。所以如果你看网上一些教学资料用的jdk1.8,还会出现问题。Jenkins安装插件要把下载地址改为国内镜像,我当时下载maven插件的时候,即使改为国内镜像也很慢。还有本篇文章尽量强调版本,因为一些老教程的Jenkins必须更新,要不然连插件都下不了。具体操作还是以官网为准吧。

调试过程中,发现jar包生成了。但没有构建成功,可以用java -jar把这个包启动一看,测试一下这个包有没有问题。

三、遇到的问题

如下报错:

Waiting for Jenkins to finish collecting data
[JENKINS] Archiving /root/.jenkins/workspace/yuzong/pom.xml to work.yinchuan/demoGIt/1.0-SNAPSHOT/demoGIt-1.0-SNAPSHOT.pom
[JENKINS] Archiving /root/.jenkins/workspace/yuzong/target/demoGIt-1.0-SNAPSHOT.jar to work.yinchuan/demoGIt/1.0-SNAPSHOT/demoGIt-1.0-SNAPSHOT.jar
/root/.jenkins/workspace/yuzong/pom.xml is not inside /root/.jenkins/workspace/yuzong/root/.jenkins/workspace/yuzong/; will archive in a separate pass
/root/.jenkins/workspace/yuzong/target/demoGIt-1.0-SNAPSHOT.jar is not inside /root/.jenkins/workspace/yuzong/root/.jenkins/workspace/yuzong/; will archive in a separate pass
FATAL: Unable to produce a script file
java.nio.charset.UnmappableCharacterException: Input length = 1
    at java.base/java.nio.charset.CoderResult.throwException(CoderResult.java:275)
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:306)
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
    at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
    at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:211)
    at java.base/java.io.BufferedWriter.flushBuffer(BufferedWriter.java:120)
    at java.base/java.io.BufferedWriter.close(BufferedWriter.java:268)
    at hudson.FilePath$CreateTextTempFile.invoke(FilePath.java:1696)
    at hudson.FilePath$CreateTextTempFile.invoke(FilePath.java:1666)
    at hudson.FilePath.act(FilePath.java:1236)
    at hudson.FilePath.act(FilePath.java:1219)
    at hudson.FilePath.createTextTempFile(FilePath.java:1660)
Caused: java.io.IOException: Failed to create a temp file on /root/.jenkins/workspace/yuzong
    at hudson.FilePath.createTextTempFile(FilePath.java:1662)
    at hudson.tasks.CommandInterpreter.createScriptFile(CommandInterpreter.java:202)
    at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:120)
    at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:92)
    at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:818)
    at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.build(MavenModuleSetBuild.java:944)
    at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:894)
    at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:526)
    at hudson.model.Run.execute(Run.java:1895)
    at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:543)
    at hudson.model.ResourceController.execute(ResourceController.java:101)
    at hudson.model.Executor.run(Executor.java:442)
Build step 'Execute shell' marked build as failure
channel stopped
Finished: FAILURE

我的解决方案:

  把shell后面的注释部分删除了,可能是这批字符有特殊字段,这个问题排查了很久。

报错信息

[yuzong] $ /bin/sh -xe /tmp/jenkins4245332453348869109.sh
channel stopped
+ cd /yuzong
+ chmod 777 /yuzong/start.sh
+ sh start.sh
start.sh: line 5: $'\r': command not found
start.sh: line 19: syntax error: unexpected end of file
Build step 'Execute shell' marked build as failure
Finished: FAILURE

shell脚本报错:“syntax error: unexpected end of file“ 原因和解决:

  解决方案

我的解决方案:在windows中,notepad++编辑器右下角可直接修改文档格式,如下图:

修改文档格式

问题解决

Waiting for Jenkins to finish collecting data
[JENKINS] Archiving /root/.jenkins/workspace/yuzong/pom.xml to work.yinchuan/demoGIt/1.0-SNAPSHOT/demoGIt-1.0-SNAPSHOT.pom
[JENKINS] Archiving /root/.jenkins/workspace/yuzong/target/demoGIt-1.0-SNAPSHOT.jar to work.yinchuan/demoGIt/1.0-SNAPSHOT/demoGIt-1.0-SNAPSHOT.jar
/root/.jenkins/workspace/yuzong/pom.xml is not inside /root/.jenkins/workspace/yuzong/root/.jenkins/workspace/yuzong/; will archive in a separate pass
/root/.jenkins/workspace/yuzong/target/demoGIt-1.0-SNAPSHOT.jar is not inside /root/.jenkins/workspace/yuzong/root/.jenkins/workspace/yuzong/; will archive in a separate pass
[yuzong] $ /bin/sh -xe /tmp/jenkins16459832435429712068.sh
channel stopped
+ cd /yuzong
+ chmod 777 /yuzong/start.sh
+ sh start.sh
+ BUILD_ID=dontKillMe
+ /yuzong/start.sh
Finished: SUCCESS

还有如下提交代码的问题,这个问题很常见。

Push rejected: Push to 123/master was rejected

原因是你在本地创建了一个项目仓库,然后gitee上创建一个仓库。

因为他们是两个不同的项目,要把两个不同的项目合并,git需要添加一句代码,在 git pull 之后,最新的版本需要添加 --allow-unrelated-histories 告诉 git 允许不相关历史合并

git pull origin2 master --allow-unrelated-histories

IDEA的Terminal框输入

然后再push就可以了

参考资料

网上的资料很多,以下我推荐的资料,文档视频都很全,细节到位。

元动力

b站尚硅谷

小结

搞这个集成部署,原理上很简单,难就在实操。稍老的教程有些地方对不上,再加上插件下载很慢,占用内存大,gitlab启来10分钟左右吧。好在网上相关资料多,有耐心多调试即可。我最后搞好也不是一下子搞成的,而是把它分成好几个部分,每个部分分别调好,总体在调试。后续还有相关内容会继续更新,敬请期待。


文章作者: 煜总
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 煜总 !
  目录