持续集成和持续交付并不是简单安装一个Jenkins就能完成的,它需要项目本身具备可重复构建的条件。对于Spring Boot应用来说,最核心的准备工作是让项目能够在命令行下完成打包,并且把环境差异外置到配置文件中。本文会先准备一个标准的Spring Boot工程,然后配置Jenkins拉取代码,再用Jenkinsfile描述构建、测试、镜像打包和部署的完整流程。整个过程基于Git仓库作为唯一触发源,目标是实现代码提交后自动产出可部署的制品。

一、准备可构建的Spring Boot应用
要让Jenkins顺利接管构建,项目目录必须保持标准Maven或Gradle结构。以Maven为例,源码放在src/main/java,资源文件放在src/main/resources,测试代码放在src/test/java。很多团队在本地用IDE直接运行,忽略了命令行构建的重要性。Jenkins只能识别命令行可执行的任务,所以第一步就是在项目根目录下执行mvn clean package,确认本地可以生成可运行的jar包。如果项目依赖了外部私有仓库,还要在settings.xml中配置镜像地址和认证信息。
Spring Boot应用通常会划分多套环境,例如开发、测试和生产。不要把所有配置写死在application.properties里,而是拆分为application-dev.yml、application-test.yml和application-prod.yml,再通过spring.profiles.active参数切换。这样做的好处是构建产物可以保持环境无关,部署时再由Jenkins注入对应环境变量。比如生产数据库地址、Redis密码等信息都不应该进入Git仓库,而是由Jenkins的凭据管理功能保存,运行时通过--spring.profiles.active=prod和--DB_PASSWORD=xxx传入。
本地验证构建时需要注意操作系统的路径差异。如果开发机是Windows,执行mvn -B clean package后产物位于target\spring-boot-demo-1.0.0.jar,盘符和反斜杠是Windows路径的一部分,例如C:\Users\admin\project\target。但Jenkins服务器通常是Linux,路径会变成/var/jenkins_home/workspace/项目名/target。在编写脚本时不要写死路径,应使用Maven默认输出目录或相对路径,避免因路径分隔符不一致导致构建失败。
二、安装配置Jenkins并接入代码仓库
Jenkins的安装方式主要有两种:直接下载war包部署在Tomcat中,或者用Docker启动官方镜像。对于测试环境,Docker方式更省事,一条命令就能运行起来。但要注意,如果后续Jenkins需要调用Docker命令来构建镜像,容器内必须挂载宿主机的Docker套接字,并安装Docker CLI。生产环境建议使用独立的Jenkins服务器,并配置数据目录的持久化,避免容器删除后丢失任务配置和历史记录。
安装完成后先安装必要插件:Git Plugin用于拉取代码,Pipeline Plugin用于声明式流水线,Docker Pipeline用于执行Docker命令,Blue Ocean可以提供图形化视图。再到全局工具配置中指定JDK和Maven版本。需要注意Jenkins运行用户对Maven本地仓库是否有写权限。如果Jenkins运行在Linux上,Maven缓存默认位于/root/.m2/repository;如果是Windows服务,则通常在C:\Windows\System32\config\systemprofile\.m2\repository。为减少权限问题,可以在Jenkins系统配置中显式设置自定义的本地仓库路径。
接入代码仓库时,先在Jenkins凭据中添加Git账号或SSH私钥。建议使用SSH密钥的方式,避免在任务配置里暴露明文密码。新建一个流水线任务,在源码管理中选择Git,填入仓库地址并选择对应凭据。触发方式可以配置为轮询SCM,比如每五分钟检查一次是否有新提交;更推荐使用Webhook,让Git平台在推送代码时主动通知Jenkins。这样构建延迟更低,也不会产生无意义的轮询请求。
三、编写Jenkinsfile实现自动化流水线
Jenkinsfile是流水线的核心,它用Groovy DSL描述整个构建过程。声明式流水线结构清晰,适合大多数Spring Boot项目。一个基本流水线包含pipeline、agent、environment和多个stage。其中agent any表示在任意可用节点上执行,environment用来定义环境变量,这些变量可以在后续阶段通过${}引用。下面是一个完整的Jenkinsfile示例:
pipeline {
agent any
environment {
APP_NAME = 'spring-boot-demo'
IMAGE_NAME = 'registry.ipipp.com/spring-boot-demo'
MAVEN_OPTS = '-Dmaven.repo.local=/var/jenkins_home/.m2/repository'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'mvn -B -DskipTests=false clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage('Package') {
steps {
sh 'cp target/spring-boot-demo-1.0.0.jar docker/app.jar'
}
}
stage('Deploy') {
steps {
sh 'docker build -t ${IMAGE_NAME}:${BUILD_NUMBER} .'
sh 'docker push ${IMAGE_NAME}:${BUILD_NUMBER}'
}
}
}
post {
failure {
echo '构建失败,请检查日志'
}
}
}这个流水线把构建和测试拆分成了两个阶段。Build阶段执行mvn clean package,如果单元测试失败,整个构建会中断并进入post中的失败处理逻辑。Test阶段其实是冗余的,因为package已经包含了测试,但为了更清晰地展示阶段划分,有些团队会单独执行mvn test来生成测试报告。Package阶段把jar包复制到docker目录,便于后续Docker构建使用。Deploy阶段通过环境变量BUILD_NUMBER给镜像打上唯一标签,避免每次都覆盖同一个latest标签。
如果不想把测试放在Build阶段重复执行,可以把mvn clean package改为mvn -DskipTests=true clean package,然后由Test阶段统一执行测试。但要注意skipTests会跳过测试代码的编译,如果测试代码本身有语法错误就无法提前发现。更稳妥的方式是使用mvn clean package -Dmaven.test.skip=false,让构建阶段执行测试,Test阶段只负责生成报告或运行集成测试。
四、构建Docker镜像并部署到目标服务器
为了让部署过程可重复且隔离运行环境,建议将Spring Boot jar包制作成Docker镜像。Dockerfile可以非常简单,只要基础镜像包含JDK,再把jar包复制进去并指定启动命令。示例内容如下:
FROM openjdk:17-jdk-slim WORKDIR /app COPY app.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
这个Dockerfile假设当前构建目录下已经存在app.jar。在Jenkins流水线中,先通过cp命令把Maven产物复制到Docker构建目录,再执行docker build。如果公司使用私有镜像仓库,还需要在Jenkins所在服务器上提前执行docker login保存认证状态。镜像标签建议使用${BUILD_NUMBER}或Git提交哈希,这样每次构建都会产生唯一版本,方便回滚和审计。
部署到目标服务器的方式主要有两种:一种是Jenkins通过SSH插件直接登录服务器执行docker run命令;另一种是部署到Kubernetes集群,使用kubectl set image滚动更新。对于中小项目,SSH方式更简单直接。可以在流水线最后增加一个阶段,用sshagent凭据登录目标机器,先停止并删除旧容器,再用新镜像启动。例如执行docker run -d --name spring-boot-demo -p 8080:8080 -e SPRING_PROFILES_ACTIVE=prod registry.ipipp.com/spring-boot-demo:${BUILD_NUMBER}。这种方式需要注意容器名称冲突,旧容器必须先清理干净。
为了避免部署失败导致服务不可用,必须提前设计回滚方案。一种简单做法是每次部署前先给当前运行容器对应的镜像打一个previous标签,新版本启动失败时,脚本自动执行docker run使用previous标签重新拉起服务。也可以使用Docker的docker tag命令保留最近三个稳定版本的镜像,这样即便连续发布两次都有问题,也能快速恢复。
五、常见问题与流水线优化
初次接入Jenkins时最容易遇到的问题有三个:Maven依赖下载慢、JDK版本与本地开发环境不一致、Git凭据无权限拉取代码。依赖下载慢可以通过配置Maven镜像源解决,例如在settings.xml中使用阿里云公共仓库。JDK版本问题需要在Jenkins全局工具配置中明确指定,同时项目pom.xml中的<java.version>标签要和构建环境保持一致。Git权限问题则要检查凭据是否使用了正确的私钥格式,以及仓库地址是否区分了大小写。
流水线运行一段时间后,Maven本地仓库会不断增大,可能占用Jenkins服务器大量磁盘空间。可以在每个任务中配置maven.repo.local指向独立的目录,并定期清理旧的构建产物。另一个常见优化点是缓存Docker构建层,把变化不频繁的依赖先复制到镜像中,再把经常变更的jar包放后面,这样每次构建镜像时只有最后一层需要重新生成,大幅提升构建速度。
为了让CI/CD流程更可靠,还可以加入质量门禁和通知机制。例如在Test阶段之后接入SonarQube扫描,设置单元测试覆盖率不得低于70%,否则将构建标记为不稳定。通知方面可以使用Email Extension插件或企业微信机器人,构建成功或失败时自动推送消息给相关开发者。最终目标是让开发人员只关注代码本身,提交之后的一切流程都由流水线自动完成。
Spring BootJenkinsCI/CD修改时间:2026-10-01 15:11:40