Spring Boot持续集成:Jenkins+GitLab+Maven+Docker自动化部署实战

发布时间:2026/9/19 6:53:53

Spring Boot持续集成:Jenkins+GitLab+Maven+Docker自动化部署实战 简介面向开发、运维及DevOps初学者的持续集成实战指南围绕Jenkins、Spring Boot、Maven、GitLab与Docker构建CI/CD链路从代码托管、构建触发到镜像交付均有完整演示。内容从基础环境安装切入先后覆盖JDK与Git准备、GitLab部署、Jenkins安装与插件配置、国内镜像加速以及Docker和Harbor私有仓库安装涉及GitLab用户权限五种等级、Jenkins初始管理员密码位置、使用清华镜像源加速插件下载等实际细节能帮助绕过安装环节的常见坑点。随后以Spring Boot项目为例演示提交代码后自动构建、推送镜像的完整过程帮助读者获得一套可复用的持续集成方案整体按安装顺序组织适合从零到一逐步操作。资源包内为1个PDF文档约1.79MB命令配置清晰便于边看边操作也适合作为排错速查参考。已有1021人浏览学习适合需要快速搭建持续集成环境的个人或团队也可据此部署一套轻量CI/CD环境验证流程。1. 从提交代码到容器启动这套持续集成管线到底解决了什么一个 Spring Boot 项目从“本地能跑”到“服务器上在跑”中间通常隔着一串手动操作Maven 打包、scp 上传、SSH 登录、找端口杀进程、重启服务。这套流程第一次做还能接受到第二十次时漏掉某一步的概率几乎和提交次数成正比。Jenkins Spring Boot Maven GitLab Docker 这套组合的核心就是把“代码提交”这个动作和“新版本容器启动”这个结果直接连起来中间的一切由一条自动化的持续集成流水线完成。这套方案适合已经用 Spring Boot 写过接口、在服务器上手动部署过 Docker 镜像的团队。你不一定需要系统学过 DevOps 理论先把“代码推送到 GitLab 触发 Jenkins 构建Maven 打成 JARDocker 封装成镜像最后容器运行起来”这条主链路跑通后面再谈自动化测试、多环境部署这些增量。2. 搭环境前先理清分工Jenkins、GitLab、Maven 和 Docker 各管哪一段持续集成涉及的工具多如果一开始就把每个工具当成独立系统去配置很容易陷入“哪个都装过哪个都没配通”的境地。正确顺序是先分清楚谁依赖谁再逐个击破连接问题。2.1 五件套的分工与版本选型这条管线里GitLab 是代码的存放地和事件源懂的一件事是“代码变了通知 Jenkins”。Jenkins 是调度中心负责把拉代码、构建、打包、推送镜像这几个动作编排成一条流水线。Maven 是构建工具它把源码变成可执行的 JAR同时管理第三方依赖。Docker 负责把 JAR 和运行环境打包成镜像让 Spring Boot 应用在任何装有 Docker 的机器上以同样方式启动。版本选型遵循“能避开跨大版本差异就不硬上”的原则。Spring Boot 3.x 通常要求 JDK 17Maven 选择 3.9.x 系列比较稳妥Jenkins 用官方 LTS 版本GitLab 优先用 Docker 方式部署也就是热词里高频出现的 docker 安装 gitlabDocker 引擎版本只要在 20.10 以上基础能力基本一致。注意一个常见误区Jenkins 构建机上的 JDK 版本必须和 Spring Boot 项目要求一致否则 Maven 编译期可能没报错运行期却抛出 UnsupportedClassVersionError。2.2 Jenkins 连接 GitLab用 API Token 还是账号密码Jenkins 要拉 GitLab 代码、接收 Webhook必须要先建立信任关系。常见做法是用 GitLab 的 Personal Access Token而不是直接拿开发者的账号密码。进入 GitLab 的 User Settings 里创建 Token权限范围勾选 api 和 read_repository 即可。在 Jenkins 的系统配置里找到 GitLab 相关设置填写 GitLab 的访问地址再把 Token 添加到凭据中最后执行连接测试。这里的报错率最高最常见的两类错误一是提示 login failed. check api token or gitlab version. log in via git if the versi二是提示 your account is pending approval from your gitlab administrator。前者多半是 Token 权限不足或 Jenkins 版本与 GitLab 的 API 不兼容排查思路依次为确认 Token 勾选了 api 权限、确认 GitLab 实例地址不是内部网络别名、必要时在系统日志里查看具体 HTTP 状态码。后者则是 GitLab 开启了用户审核机制新创建的账号必须由管理员在 Admin Area 里批准后才能访问仓库和 Jenkins 配置本身无关。2.3 Maven 配置阿里云仓库先把依赖下载这关过了再谈构建如果原始仓库地址是 repo.maven.apache.org在国内环境构建时很容易卡在下载依赖这一步Jenkins 构建日志里满屏下载超时。这里建议在构建机上统一配置阿里云仓库镜像而不是在项目里逐个 pom.xml 修改原因是一台构建机会跑多个项目全局配置维护成本最低。mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror把上面的 mirror 段加进 Maven 安装目录下 conf/settings.xml 的 mirrors 节点里。mirrorOf 写星号表示所有仓库请求都走阿里云镜像id 可以自定义但不要和仓库 id 重复。配置完成后可以先在命令行手动执行一次 mvn clean package确认依赖能够完整下载。Jenkins 里还需要在全局工具配置中指定 Maven 的安装路径建议使用“自动安装”并指定版本让 Jenkins 自己管理 Maven 的下载和升级。3. 创建第一条流水线从 GitLab 拉代码到 Maven 构建出 JAR环境连通之后核心工作就是把 Jenkins 里的一条 Job 配置成完整的构建流程。如果使用传统的自由风格项目每一步都要在 UI 上点选排错和复用都困难。这里采用 Pipeline 方式把构建流程写成 Jenkinsfile纳入 GitLab 仓库版本管理后续改动只需提交代码不需要再进 Jenkins 界面操作。3.1 插件清单先装这几款别被推荐的打包插件吓到Jenkins 首次安装时界面会提示安装大量插件这里建议只装明确要用的减少后续升级冲突。最精简的插件集合包括GitLab 插件负责集成 GitLab API 和 Webhook、Pipeline 插件提供流水线语法支持、Docker Pipeline 插件让流水线里能执行 docker 命令和操作镜像、Credentials Binding 插件用于把密钥安全地注入环境变量。插件安装源如果在国外在“系统管理 → 插件管理 → 高级”里将更新站点 URL 替换成国内镜像地址保存后先刷新插件列表再安装。插件之间也有版本依赖比如 GitLab 插件更新后可能要求 Jenkins LTS 版本同步升级如果某个插件无法安装优先检查 Jenkins 版本是否太旧。3.2 最小 Jenkinsfile环境变量、镜像标签和并发加锁Pipeline 脚本有两种写法声明式更易读适合团队协作下面是能直接跑通的一条最小流水线pipeline { agent any environment { REGISTRY registry.example.com/springboot-demo IMAGE_TAG ${BRANCH_NAME}-${BUILD_NUMBER} } stages { stage(Checkout) { steps { checkout scm } } stage(Build) { steps { sh mvn clean package -DskipTests } } stage(Docker) { steps { sh docker build -t ${REGISTRY}:${IMAGE_TAG} . docker push ${REGISTRY}:${IMAGE_TAG} } } } }这段脚本的逻辑是Checkout 阶段从 GitLab 拉取当前分支代码Build 阶段执行 Maven 打包并跳过单元测试以避免构建时间过长Docker 阶段构建镜像并推送到镜像仓库。这里需要说明两个 Jenkins 可用环境变量BRANCH_NAME 是当前构建的分支名BUILD_NUMBER 是构建序号两者拼接作为镜像标签的好处是每次构建的镜像 Tag 严格唯一不会出现覆盖旧镜像导致回滚无门的情况。如果想要镜像标签更短可以用 GIT_COMMIT 环境变量截取前 8 位作为版本号例如${GIT_COMMIT.take(8)}但注意在多分支流水线里 GIT_COMMIT 代表触发这次构建的那个 Commit比 BUILD_NUMBER 能更直接对应到代码版本。3.3 Webhook 触发让 GitLab 推送事件自动拉起 Jenkins 构建手动点击“立即构建”只是验证链路真正意义上的持续集成必须由代码事件驱动。在 Jenkins Job 配置里勾选 GitLab 相关的触发方式Jenkins 会生成一个 Webhook URL 和 Secret Token把这个 URL 填到 GitLab 项目的 Settings 里的 Webhooks 中。GitLab 侧触发事件选择 Push events如果想要更精细地控制在 Jenkins 的触发配置里设置分支过滤使用正则表达式限定只对 master 或 develop 这类主干分支生效。开发分支每推送一次都触发构建很快会挤爆构建队列和镜像仓库。热词里提到的“gitlab clone with http 怎么 clone 设置为域名不是机器 ID”提醒我们GitLab 的 External URL 如果配置成容器 ID 或内网 IPJenkins 回调 Webhook 时会连不上务必保证这个 URL 是 GitLab 所在服务器可达的域名。4. 构建 Spring Boot 镜像与容器编排Dockerfile 和 docker-compose 的配合代码变成 JAR 只是中间产物线上运行依赖的是 Docker 镜像。这一章解决两个问题怎么写出适合 Spring Boot 应用的 Dockerfile以及 Jenkins 执行 Docker 命令时可能遇到什么权限阻碍。4.1 Spring Boot 的 Dockerfile 模板时区、JVM 参数与分层构建很多项目直接在基础镜像里打包 JDK再往里面 COPY JAR镜像体积大且每次构建都传输巨大上下文。常见做法是直接基于 JRE 镜像并设置容器时区为 Asia/Shanghai避免 Spring Boot 应用打印的日志时间和服务器相差 8 小时。FROM eclipse-temurin:17-jre ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone WORKDIR /app ARG JAR_FILEtarget/*.jar COPY ${JAR_FILE} app.jar EXPOSE 8080 ENTRYPOINT [java,-XX:UseG1GC,-Xms256m,-Xmx512m,-jar,app.jar]把 JAR_FILE 声明为 ARG 而不是直接写死路径是为了让同一个 Dockerfile 能兼容不同 module 结构。JVM 参数采用固定写法而非调优工具生成的值是因为容器内的内存上限由 Docker 约束-Xmx 设置的数值要小于容器分配的内存上限否则会触发 OOM Kill。镜像构建完成后用 docker images 检查多出的 tag 是 springboot-demo 分支名加构建序号。4.2 docker-compose 管理运行参数端口映射、日志轮转与依赖顺序镜像只是静态产物真正的运行参数在容器启动那一刻才确定。一条 docker run 命令能解决单次启动但端口、日志、环境变量这些配置写进 docker-compose.yml 才能被团队复用。下面是常见的服务编排模板services: app: image: registry.example.com/springboot-demo:master-42 ports: - 8080:8080 environment: - SPRING_PROFILES_ACTIVEtest - TZAsia/Shanghai logging: driver: json-file options: max-size: 50m max-file: 3这里没有写 version 字段因为 Docker Compose V2 已经默认使用新版语法写了 version 反而会产生弃用警告。environment 里的 SPRING_PROFILES_ACTIVE 是 Spring Boot 项目读取 application-test.yml 的开关这条可以灵活切换不同环境配置。日志配置 log opts 限制单份日志文件大小和保留份数避免 Spring Boot 应用不做日志切分时服务器磁盘被 console.log 持续占用。4.3 Jenkins 容器内执行 docker挂载 docker.sock 与权限边界如果 Jenkins 以容器方式运行直接在流水线里执行 docker build 命令会得到 docker: command not found原因是容器内的 PATH 里没有指向宿主机的 Docker CLI。常见做法是把宿主机的 Docker 套接字直接挂载到 Jenkins 容器内让 Jenkins 容器通过宿主机的守护进程执行构建。docker run -d --name jenkins \ -v /var/run/docker.sock:/var/run/docker.sock \ -v jenkins_home:/var/jenkins_home \ -p 8080:8080 \ jenkins/jenkins:lts挂载 docker.sock 的代价是Jenkins 容器内拥有相当于宿主机 root 的 Docker 权限一旦 Jenkins 被攻破宿主机的容器环境也暴露在风险中。生产环境下优雅的替代方案是配置一个独立的 Docker HostJenkins 通过 DOCKER_HOST 环境变量远程访问但前提是先处理好 TLS 证书认证否则安全级别比挂载 socket 更低。5. 排错清单这条链路上最常见的六个问题与验证技巧整套流水线涉及五次不同工具的交互联调时出现的报错分散在各个日志里。最后这一章把高频问题整理成表再给出一个能快速确认“这次发布真的生效”的验证方法。报错现象所在环节原因与处理login failed. check api token or gitlab versionJenkins 连接 GitLabToken 权限不足或 GitLab API 版本不兼容检查 api 权限与 External URLyour account is pending approvalGitLab 登录/拉代码管理员未审核新用户在 Admin Area 中批准mvn 依赖下载缓慢或失败Maven 构建未配置阿里云镜像或 settings.xml 路径没被 Jenkins 识别容器时间比服务器早 8 小时Docker 运行基础镜像时区非 Asia/Shanghai在 Dockerfile 中设置 TZdocker: command not foundPipeline 执行Jenkins 容器内未挂载 Docker 套接字或未安装 Docker CLIIDEA 启动 Spring Boot 不显示端口号本地调试端口被占用或 application.yml 配置读取失败优先查控制台 ERROR 堆栈表格里的前三个问题都发生在持续集成链路的前半段处理完这些基本可以保证代码能被干净地构建成镜像。后半段的问题集中在运行时行为这类问题 Jenkins 日志无法给出信号必须到运行容器内部去看。验证一次发布是否真正生效不能只看构建状态变成蓝色。下面是检查思路先确认运行容器的镜像 ID 和这次构建的镜像 ID 一致再看健康检查接口是否返回预期 JSON。sha$(git rev-parse --short HEAD) image_id$(ssh deployhost docker inspect --format {{.Image}} springboot-demo) if [[ $image_id *$sha* ]]; then echo 镜像版本一致 else echo 镜像版本异常可能拉取到旧镜像 fi curl -s http://example.com/api/health | jq .status日志和探活接口双确认是最直接的发布验收手段。docker inspect 的 Image 字段拿到的是镜像 ID这个值在每次构建时都会变化如果发布后这个 ID 没变那么无论 Jenkins 构建日志写得多漂亮实际运行代码根本没换。这时候第一件事不是重新构建而是去检查部署步骤里的 image tag 是否写死成了上一次的结果。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/19 6:53:53

ValidX构建集成:Maven/Gradle契约验证零侵入实践

1. ValidX 是什么?为什么它值得你花时间集成进 Maven/Gradle 构建流程? ValidX 不是一个广为人知的开源库,也不是 Apache 或 Gradle 官方生态里的标准组件——它本质上是一套面向企业级 Java 应用的 运行时契约验证框架 ,核心定…

2026/9/19 6:48:53

HI3516CV610海思SoC开发实战:从选型到量产全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 6:48:53

多模态小样本学习实战:跨模态对齐与原型分类

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 8:03:56

Kafka如何成为实时上下文引擎赋能AI

1. “Kafka已正式接入AI”不是一句宣传口号,而是实时数据管道的范式迁移最近在几个技术群和内部架构评审会上,反复看到这句话被当作PPT首页标题:“Kafka已正式接入AI”。起初我以为是某家公司在搞营销噱头——毕竟Kafka作为成熟的消息中间件&…

2026/9/19 8:03:56

计算机视觉PPT实战:内容架构、脚本配图与YOLO算法页设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 8:03:56

AI Agent对话管理:状态追踪与意图识别的技术实践

1. AI Agent对话管理的核心挑战在智能对话系统开发中,让AI Agent像人类一样自然流畅地管理对话流程,是提升用户体验的关键瓶颈。我经历过多个对话系统项目,最深刻的体会是:单轮问答可以靠强大的语言模型硬撑,但真正的考…

2026/9/19 8:03:56

ATP-EMTP在高压绝缘子串仿真中的关键技术应用

1. 绝缘子串仿真研究背景与意义在高压输电线路运行中,绝缘子串作为关键部件,其性能直接影响电力系统的安全稳定。实际运行中,绝缘子会面临雷电冲击、污秽积累、材料老化等多重考验。传统试验方法存在成本高、周期长、破坏性大等局限&#xff…

2026/9/19 7:58:56

SPL06气压温度传感器驱动开发:SPI通信与补偿算法实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码