资讯动态

Docker 安装 Jenkins 实现 Spring Boot 持续集成与手动部署实战

发布时间:2026/10/13 17:41:54 来源:尧图企业网站定制
1. 为什么这套组合至今仍是中小团队的高性价比选择先把结论摆在前面用 Docker 跑 Jenkins配合代码托管平台做触发源再手动把 Spring Boot 产物部署到目标机器上这套流程听起来土但它在中小团队、个人项目、内部工具类系统里依然是投入产出比最高的方案之一。原因不复杂——它把持续集成和持续部署这两件事拆开了CI 部分交给 Jenkins 自动化CD 部分保留人工确认既省掉了大量重复构建的体力活又不会因为一次误提交就把线上环境搞崩。我见过太多团队一上来就追求全自动流水线结果光是调试部署脚本、处理权限、排查环境差异就耗掉几周最后流水线跑通了业务代码却没写几行。反过来先把 Jenkins 用 Docker 跑起来把拉代码、编译、打包、产出 jar这一段自动化部署环节手动执行几条命令整个链路一两天就能跑通后续再逐步把部署也自动化这才是符合实际节奏的做法。这篇文章面向的是这样几类人刚接触 CI/CD 想找个能落地的入门方案的后端开发者手头有几个 Spring Boot 项目、每次发版都靠手动打包上传的独立开发者以及团队里被安排搭一套构建环境但不想引入太重基础设施的运维或全栈同学。整套方案的核心关键词就是Docker 安装 Jenkins、代码托管平台触发构建、Spring Boot 手动部署我会把每一步为什么这么做、参数怎么定、坑在哪里都讲清楚。需要提前说明的是本文的部署环节采用手动方式这不是偷懒而是一种刻意的设计选择。手动部署意味着每次上线前有人工确认节点对于没有完善监控和回滚机制的团队来说这道人工闸门能挡掉相当一部分事故。等你的自动化测试、健康检查、灰度发布都成熟了再把这道闸门去掉也不迟。2. 用 Docker 跑 Jenkins 的镜像选型与目录规划2.1 为什么不用 apt 或 yum 直接装 Jenkins很多人第一次搭 Jenkins 的习惯是照着官方文档用包管理器安装装完发现 Java 版本冲突、插件目录散落各处、想迁移环境得重新装一遍。用 Docker 的核心价值在于环境隔离和可迁移Jenkins 本体、它依赖的 JDK、它下载的一堆插件全部封装在容器和挂载卷里换台机器把卷拷过去就能恢复这对没有专职运维的团队太重要了。另一个现实原因是版本管理。Jenkins 的长期支持版和每周更新版差异不小插件对核心版本还有兼容要求。用 Docker 镜像可以精确锁定某个版本标签比如锁定到某个 LTS 大版本避免某天手滑升级导致插件集体罢工。包管理器安装的话系统一更新就可能被动升级风险不可控。还有一点容易被忽略Jenkins 构建 Spring Boot 项目时需要 Maven 或 Gradle需要 JDK这些工具链版本最好和你的项目保持一致。用 Docker 可以把构建工具链也纳入镜像管理或者干脆用 Jenkins 的构建时拉取工具机制让每个项目用自己声明的版本互不干扰。2.2 镜像标签怎么选别盲目追新拉镜像的时候你会看到一堆标签latest、lts、lts-jdk17、jdk21等等。我的建议是永远不要用 latest因为它的内容会随时间变化今天跑通的配置明天可能就出问题。选一个带 JDK 版本号的 LTS 标签比如lts-jdk17这种既保证了稳定性又明确了运行环境。选 JDK 版本要和你的 Spring Boot 项目对齐。Spring Boot 3.x 要求 JDK 17 起步如果你还在用 Spring Boot 2.xJDK 8 或 11 也能跑。这里有个坑Jenkins 容器自带的 JDK 是给 Jenkins 自己用的你的项目构建时用的 JDK 可以是另一个版本。如果两者不一致要么在容器里额外装一个 JDK要么用 Jenkins 的工具配置功能让构建时自动下载指定 JDK。我一般倾向于让容器 JDK 和项目 JDK 保持一致省去很多麻烦。拉取命令大致是这样docker pull jenkins/jenkins:lts-jdk17拉完之后用docker images确认一下镜像大小通常几百 MB 到 1GB 出头属于正常范围。如果拉取很慢可以配置镜像加速这个各家云厂商都有公开的加速地址配置到 Docker 的 daemon 配置里即可。2.3 挂载目录的设计决定了你日后迁移的痛苦程度这是整个环境搭建里最值得花心思的部分。容器本身是无状态的删了重建很容易但 Jenkins 的所有配置、任务、构建历史、插件都在数据目录里。如果不做挂载容器一删你辛苦配的一切全没了。Jenkins 容器里需要持久化的核心目录是/var/jenkins_home。我建议在宿主机上单独建一个目录比如/data/jenkins/home然后挂载进去。这样备份的时候直接打包这个目录就行迁移的时候拷到新机器同样位置启动容器就能恢复。mkdir -p /data/jenkins/home chown -R 1000:1000 /data/jenkins/home注意那个chown这是新手最容易踩的坑。Jenkins 镜像里默认用 uid 1000 的用户运行如果你挂载的宿主机目录属主是 root容器启动时会因为没权限写数据目录而报错日志里会提示权限拒绝。把目录属主改成 1000 就能解决。如果你宿主机上 uid 1000 已经被别的用户占了那就得用--user参数指定运行用户或者调整目录权限这个后面讲启动参数时再说。除了 home 目录如果你打算让 Jenkins 直接操作 Docker比如在流水线里构建镜像还需要把宿主机的 Docker 套接字挂载进去。但这一步有安全考量等于把宿主机 Docker 的控制权交给了容器是否要做取决于你的信任边界。本文的手动部署方案其实不太需要容器内操作 Docker所以可以先不挂保持最小权限。2.4 启动参数逐条拆解启动命令看着简单但每个参数都有讲究docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v /data/jenkins/home:/var/jenkins_home \ -v /etc/localtime:/etc/localtime:ro \ --restartunless-stopped \ jenkins/jenkins:lts-jdk17-p 8080:8080是 Web 界面端口这个大家都知道。-p 50000:50000是 Jenkins 的代理通信端口如果你以后要加构建节点agent这个端口必须开。现在用不上也建议先映射着省得以后改。-v /etc/localtime:/etc/localtime:ro是让容器时间和宿主机一致。别小看这个构建日志的时间戳如果和你的时区差几个小时排查问题时会很痛苦。只读挂载:ro就够了容器不需要改宿主机时间。--restartunless-stopped保证宿主机重启后 Jenkins 自动起来除非你手动停过它。这个策略比always更符合直觉手动停掉的服务不应该被自动拉起来。启动后用docker logs -f jenkins看日志会看到一行初始管理员密码形如Please use the following password to proceed to installation: a1b2c3d4e5f6...这个密码也可以从挂载目录里的secrets/initialAdminPassword文件读到。拿到密码后浏览器访问http://你的机器IP:8080进入初始化向导。2.5 初始化向导里那些值得犹豫的选项向导第一步会让你选安装推荐的插件还是选择插件安装。我的建议是选推荐插件它会装 Git、Pipeline、凭据管理等一批基础插件省得你一个个找。虽然会装一些你暂时用不上的但体积影响不大而且后续大概率会用到。第二步创建管理员账号。这里有个细节向导默认会创建一个叫 admin 的管理员但初始密码那个账号其实叫admin之外的名字。建议在这一步直接创建你自己的管理员账号密码设强一点然后把初始密码那个临时账号禁用或改密。很多人图省事跳过这步结果线上 Jenkins 一直用着初始账号安全隐患很大。第三步配置实例地址填你实际访问的地址就行比如http://192.168.1.100:8080/。这个地址会影响邮件通知里的链接、构建触发回调地址等填错了后面改起来麻烦。装完推荐插件后建议再手动补几个Git 插件通常已包含、Pipeline已包含、Credentials Binding已包含、Maven Integration如果用 Maven 构建。如果推荐列表里没有 Maven Integration去插件管理里搜一下装上。3. 打通代码托管平台与 Jenkins 的认证链路3.1 凭据类型的选择SSH 密钥还是访问令牌Jenkins 要拉代码就得有访问代码仓库的凭据。常见两种方式SSH 密钥和 HTTPS 访问令牌。两者各有适用场景选错了后面会反复折腾。SSH 密钥的好处是配置一次可以长期用不受令牌过期影响适合机器对机器的长期集成。缺点是密钥管理稍微麻烦公钥要传到代码平台私钥要存进 Jenkins 凭据而且如果多个项目用同一个密钥权限粒度不好控制。HTTPS 访问令牌的好处是权限可以精细控制比如只给读权限而且可以随时吊销。缺点是令牌有有效期到期要换忘了换就会导致构建突然失败。我的建议是内部可信环境用 SSH 密钥跨团队或权限敏感的场景用访问令牌。本文为了通用性用访问令牌的方式演示因为它配置起来更直观不需要生成密钥对。在代码托管平台的设置里找到访问令牌或个人访问令牌入口创建一个令牌权限勾选仓库读取即可。如果后续要让 Jenkins 回写构建状态到代码平台还需要额外的权限。创建后令牌只显示一次务必先复制保存。3.2 在 Jenkins 里正确添加凭据进入 Jenkins 的系统管理→凭据→系统→全局凭据添加一个用户名密码类型的凭据。用户名填你的代码平台账号密码填刚才生成的访问令牌。ID 可以留空让 Jenkins 自动生成也可以自己起个有意义的名字比如git-access-token方便在流水线里引用。这里有个常见误区有人把令牌当成密码直接填用户名随便写。实际上很多代码平台校验的是用户名令牌组合用户名必须是你真实的账号名否则认证会失败。如果用的是某些平台的仅令牌认证方式用户名可以填任意非空值但具体要看平台文档。添加完凭据后建议立刻在 Jenkins 里建一个测试任务验证一下。新建一个自由风格任务源码管理选 Git填仓库地址凭据选刚添加的保存后点立即构建。如果能在工作空间里看到代码被拉下来说明认证链路通了。这一步别跳过后面所有构建都依赖它。3.3 仓库地址的两种写法与踩坑点仓库地址有 SSH 和 HTTPS 两种写法。用访问令牌的话必须用 HTTPS 地址形如https://代码平台域名/组织/仓库.git。用 SSH 密钥的话用git域名:组织/仓库.git这种形式。一个高频坑是仓库地址填对了但 Jenkins 所在机器无法解析代码平台的域名或者网络不通。这种情况构建日志里会卡在拉取阶段报连接超时或域名解析失败。排查方法是进 Jenkins 容器里手动执行git clone试试或者ping一下域名。容器内的网络和宿主机不一定完全一致特别是公司内网有代理的情况下容器可能没继承代理配置。另一个坑是仓库太大导致拉取超时。Jenkins 默认的 Git 超时时间可能不够可以在任务配置的附加行为里调整超时或者用浅克隆--depth 1只拉最近一次提交。浅克隆对构建来说通常够用能显著加快拉取速度但如果你需要基于历史提交做变更分析就不能用浅克隆。3.4 触发方式轮询、Webhook 还是手动代码提交后怎么让 Jenkins 知道该构建了三种方式轮询Poll SCM是 Jenkins 定时去问代码平台有没有新提交有就构建。配置简单但实时性差而且频繁轮询会给代码平台压力。适合代码平台不支持 Webhook 的场景。Webhook是代码平台在收到提交后主动通知 Jenkins。实时性好是推荐方式。配置需要在代码平台的仓库设置里加一个 Webhook地址填 Jenkins 的触发地址形如http://Jenkins地址:8080/generic-webhook-trigger/invoke?tokenxxx或项目专用的构建触发地址。不同代码平台的 Webhook 配置界面不同但核心就是填 URL 和选择触发事件通常是 push。手动触发就是点按钮构建适合发版这种需要人工确认的场景。实际项目中我通常组合使用日常开发分支用 Webhook 自动构建发版分支用手动触发。这样既保证了开发效率又给发版留了确认节点。Webhook 配置有个容易忽略的点Jenkins 必须能被代码平台访问到。如果你的 Jenkins 跑在内网代码平台在公网Webhook 就推不过来。这种情况要么用轮询要么在内网和公网之间做转发。本文假设 Jenkins 和代码平台网络可达如果不可达退而求其次用轮询也能跑通。4. Spring Boot 项目的构建任务配置与产物管理4.1 自由风格任务还是流水线任务Jenkins 有两种主要任务类型自由风格Freestyle和流水线Pipeline。自由风格通过界面点选配置上手快适合简单构建。流水线用代码描述构建过程Jenkinsfile可版本化、可复用适合复杂流程。对于拉代码→编译→打包这种线性流程自由风格完全够用而且配置直观出了问题一眼能看出哪步配错了。流水线虽然更强大但学习曲线陡调试也麻烦。我的建议是先用自由风格把流程跑通等流程稳定且需要多环境复用时再迁移到流水线。本文以自由风格为例因为它对新手更友好。如果你已经熟悉流水线把下面的步骤翻译成 Jenkinsfile 也不难。4.2 源码管理配置的细节新建自由风格任务后第一块是源码管理。选 Git填仓库地址选之前配好的凭据。分支填你要构建的分支比如*/main或*/develop。如果填*会构建所有分支通常不是你想要的。附加行为里可以加一些优化。比如浅克隆减少拉取量检出到子目录用于多仓库场景清理工作空间保证每次构建从干净状态开始。清理工作空间这个选项建议勾上避免上次构建的残留文件影响这次结果。代价是每次都要重新拉全量代码如果仓库大构建时间会增加。权衡下来构建结果的可靠性比省那点时间更重要。4.3 构建触发器的组合策略前面讲过触发方式这里说具体配置。在构建触发器里勾选轮询 SCM日程表填H/5 * * * *表示每 5 分钟检查一次。H是 Jenkins 的哈希符号会让不同任务的检查时间错开避免整点集中请求。或者勾选GitHub hook trigger for GITScm polling如果代码平台是 GitHub 系配合 Webhook 使用。日程表用的是 cron 语法但 Jenkins 对H的支持是个特色。比如H H * * *表示每天随机一个时间点执行一次适合做每日构建。别小看这个随机化如果几十个任务都配0 0 * * *午夜零点会有一波请求高峰。4.4 构建步骤Maven 命令怎么写才稳构建环节选调用顶层 Maven 目标目标填clean package -DskipTests。这里几个参数值得说明clean清理上次构建产物避免旧 class 文件混入。package执行编译打包。-DskipTests跳过测试加快构建速度。但跳过测试有风险如果测试里有重要的集成检查跳过就等于放弃了这道防线。我的做法是日常构建跳过测试发版构建不跳过。可以在任务里用参数化构建让触发时选择是否跑测试。如果项目需要指定 JDK 版本在构建环境里勾选提供 JDK或提供 Maven选择你配置好的版本。这要求你事先在系统管理→全局工具配置里配好 JDK 和 Maven 的安装。可以配成自动下载也可以指向容器内已有的路径。构建日志里会输出 Maven 的下载依赖过程。第一次构建会下载大量依赖比较慢后续有本地仓库缓存就快了。但容器重建后缓存会丢如果依赖下载是瓶颈可以把 Maven 本地仓库也挂载出来持久化。4.5 构建产物的归档与定位构建成功后Spring Boot 的产物通常在target/目录下形如项目名-版本号.jar。在构建后操作里添加归档成品填target/*.jarJenkins 会把 jar 保存下来可以在构建页面直接下载。归档的意义在于每次构建的产物都有记录出问题可以回溯到具体某次构建的产物。手动部署时直接从 Jenkins 下载对应版本的 jar比在本地重新打包可靠得多。这里有个细节如果target下有多个 jar比如有 sources jar、javadoc jar*.jar会把它们都归档。可以用更精确的匹配比如target/项目名-*.jar排除掉 sources 和 javadoc。或者干脆在 Maven 配置里关掉这些附加产物的生成。产物命名建议带上版本号和构建号比如在 Maven 的finalName里用${project.version}-${build.number}这样每个产物都唯一部署时不会搞混。不过build.number是 Jenkins 的变量Maven 直接读不到需要在构建时通过参数传入稍微麻烦点。简单做法是用 Maven 的版本号配合 Jenkins 的构建号在归档文件名里区分。5. 手动部署 Spring Boot 产物的完整操作链路5.1 为什么保留手动部署这道工序前面提过手动部署是刻意保留的人工闸门。具体来说它带来三个好处上线前有人确认避免自动部署把未验证的代码推上生产部署过程可见执行命令的人清楚每一步在做什么出问题能立刻反应回滚简单手动部署通常保留了上一个版本的 jar回滚就是换个文件重启。当然手动部署也有代价容易漏步骤、依赖个人经验、无法做到秒级发布。所以它适合发布频率不高比如一周几次、团队规模小、对发布速度要求不极端的场景。如果你的业务需要一天发几十次那必须上自动化部署手动方式会成为瓶颈。5.2 从 Jenkins 取产物的几种方式产物归档后取用方式有几种。最简单的是在 Jenkins 构建页面点归档的 jar 直接下载到本地再上传到目标服务器。这种方式适合偶尔发版但每次手动下载上传很繁琐。稍微好一点的是用命令行工具从 Jenkins 拉取。Jenkins 提供了直接的产物下载地址形如http://Jenkins地址:8080/job/任务名/构建号/artifact/target/项目.jar。用curl或wget就能拉配合脚本可以半自动化。curl -u 用户名:API令牌 -O http://Jenkins地址:8080/job/任务名/lastSuccessfulBuild/artifact/target/项目.jar注意这里的认证用 API 令牌比用密码安全。API 令牌在用户的配置页面生成。lastSuccessfulBuild是 Jenkins 的内置变量指向最近一次成功的构建用它就不用每次改构建号。如果目标服务器能直接访问 Jenkins可以在服务器上执行这条命令拉取产物省去本地中转。如果访问不了就得先下载到本地再上传。5.3 目标服务器上的目录结构与启动脚本目标服务器上建议规划一个清晰的目录结构/opt/app/ ├── releases/ │ ├── 项目-20240101-1.jar │ └── 项目-20240102-2.jar ├── current - releases/项目-20240102-2.jar ├── logs/ └── start.shreleases存放历史版本current是个软链接指向当前运行的版本logs放日志。这种结构的好处是回滚只需改软链接指向然后重启服务。启动脚本大致这样#!/bin/bash APP_HOME/opt/app JAR$APP_HOME/current LOG$APP_HOME/logs/app.log PID$(ps -ef | grep $JAR | grep -v grep | awk {print $2}) if [ -n $PID ]; then kill -15 $PID sleep 5 if ps -p $PID /dev/null; then kill -9 $PID fi fi nohup java -jar $JAR \ --spring.profiles.activeprod \ -Xms512m -Xmx1024m \ $LOG 21 这里用kill -15先发优雅停止信号给应用时间处理完手头请求、关闭连接池。等 5 秒还没停再kill -9强杀。直接kill -9可能导致数据不一致能优雅停就优雅停。JVM 参数-Xms512m -Xmx1024m是堆内存初始值和最大值。设成一样可以避免运行中堆扩容带来的性能波动。具体数值要根据服务器内存和应用实际需求定别照抄。设太小会频繁 GC设太大可能挤占其他进程内存。5.4 部署操作的完整步骤与验证一次完整的手动部署流程在 Jenkins 上确认目标构建成功产物已归档。从 Jenkins 拉取 jar 到目标服务器的releases目录文件名带上版本或构建号。更新current软链接指向新 jarln -sfn /opt/app/releases/新jar /opt/app/current。执行start.sh重启服务。观察日志tail -f /opt/app/logs/app.log确认启动无异常。访问健康检查接口或业务接口验证服务正常。如果异常把current指回上一个版本重启回滚完成。第 6 步的验证很关键别启动完就不管了。Spring Boot 应用启动成功不代表业务正常可能数据库连不上、配置读错了、端口被占用了。至少要访问一个能反映核心依赖状态的接口。如果项目有健康检查端点比如 Spring Boot Actuator 的/actuator/health优先用它。5.5 部署环节的常见故障与排查思路端口被占用启动日志报Address already in use。说明上一个进程没停干净或者有别的程序占了端口。用lsof -i:端口或netstat -tlnp | grep 端口找到占用进程处理掉。启动后立刻退出日志里可能有异常堆栈。常见原因是配置文件缺失、数据库连不上、依赖的中间件不可达。仔细看日志开头的报错通常能定位到具体原因。启动慢或卡住可能是连某个外部服务超时。检查配置里的连接地址、超时设置。有时候是 DNS 解析慢可以在/etc/hosts里加静态解析。内存溢出日志报OutOfMemoryError。要么调大-Xmx要么排查代码里的内存泄漏。临时调大能救急但根治还得看代码。软链接更新后仍跑旧版本检查current是否真的指向了新文件用ls -l /opt/app/current确认。有时候是脚本里路径写死了没走软链接。6. 让这套流程更耐用的几个加固点6.1 构建环境的依赖缓存前面提过容器重建后 Maven 本地仓库会丢下次构建要重新下载所有依赖。如果依赖多这可能是几分钟甚至十几分钟的浪费。解决办法是把 Maven 本地仓库挂载出来持久化。在启动 Jenkins 容器时加一个挂载-v /data/jenkins/m2:/var/jenkins_home/.m2或者在全局工具配置里把 Maven 的本地仓库路径指到挂载目录。这样依赖只下载一次后续构建直接命中缓存。代价是占磁盘空间定期清理一下没用的依赖即可。6.2 构建失败的快速定位习惯构建失败时第一件事是看日志里第一个 ERROR 或 BUILD FAILURE 出现的位置。Jenkins 的日志很长从后往前翻容易漏掉根因从前往后找到第一个报错点更高效。常见失败原因归类依赖下载失败网络问题或仓库地址错、编译错误代码问题、测试失败代码或环境问题、打包失败配置问题。定位到类别后排查方向就清晰了。如果是偶发失败比如网络抖动导致的依赖下载失败可以配置构建重试。Jenkins 本身没有内置重试但可以用插件或在流水线里写重试逻辑。自由风格任务的话手动再点一次构建通常就能过。6.3 凭据与权限的最小化原则Jenkins 里的凭据能访问代码仓库一旦泄露影响不小。几个加固建议凭据只给必要的权限比如只读仓库定期轮换访问令牌不同项目用不同凭据避免一个泄露全部沦陷Jenkins 的 Web 界面不要暴露在公网至少加一层认证或限制访问来源。如果团队多人使用 Jenkins用 Jenkins 的权限管理给不同人分配不同权限。普通开发者只能触发构建和看日志不能改任务配置和系统设置。这个在系统管理→全局安全配置里设置。6.4 从手动部署平滑过渡到自动部署的路径这套流程跑顺之后如果想进一步自动化可以按这个顺序推进先把拉取产物重启服务写成脚本在目标服务器上手动执行脚本完成部署然后把脚本调用集成到 Jenkins 的构建后步骤用 SSH 插件远程执行最后加上健康检查和自动回滚失败时自动切回上一版本。每一步都别跳因为自动化部署的坑往往在细节里——SSH 免密配置、远程执行的环境变量、脚本的幂等性、并发部署的锁。一步步来每步验证稳定了再进下一步比一次性全自动然后天天救火要靠谱得多。6.5 日志与构建历史的保留策略Jenkins 默认保留所有构建历史时间长了磁盘会满。在任务配置里可以设置丢弃旧的构建比如保留最近 30 次或者保留最近 30 天。归档的产物也受这个策略影响如果产物重要要么单独备份要么把保留数量设大一点。构建日志本身也占空间但通常比产物小。如果排查问题需要历史日志保留策略别设太激进。我的习惯是保留最近 50 次构建产物保留最近 10 次兼顾排查需求和磁盘占用。目标服务器上的日志也要管理。Spring Boot 的日志如果不切割几天就能涨到几个 GB。用 logback 配置按天切割和保留天数或者用系统的 logrotate 处理。日志写满磁盘导致服务挂掉的事故我见过不止一次。7. 我在实际搭建中踩过的几个真实坑第一个坑是容器内时区不对导致构建日志时间错乱。当时没挂载/etc/localtime容器默认 UTC 时间和本地差 8 小时。排查一个为什么凌晨的构建问题时被误导了很久后来才发现是时区问题。挂载时区文件后解决。第二个坑是挂载目录权限。第一次启动 Jenkins 时没改目录属主容器反复重启日志里报权限拒绝。当时不知道 Jenkins 用 uid 1000 运行折腾了半天。后来chown -R 1000:1000一下就好了。这个坑几乎每个新手都会踩。第三个坑是 Webhook 配置后不触发。检查发现是 Jenkins 的地址填的是localhost代码平台从外部访问不到。改成实际 IP 后正常。这个提醒我们配置里凡是涉及地址的地方都要想清楚谁访问谁别用相对地址或 localhost。第四个坑是 Maven 构建时 JDK 版本不匹配。项目要求 JDK 17但 Jenkins 容器默认用的是别的版本编译报错。后来在全局工具配置里指定了 JDK 17并在任务里选用才解决。这个坑的教训是构建环境的版本一定要和项目要求对齐别想当然。第五个坑是手动部署时忘了停旧进程新进程起不来报端口占用。后来在启动脚本里加了自动停旧进程的逻辑才避免了这个低级错误。手动操作容易漏步骤能用脚本固化的就固化。这些坑的共同点是都不是技术难题而是环境配置和操作习惯的问题。但恰恰是这些细节决定了这套流程是能用还是好用。把每个环节的边界条件想清楚把重复操作脚本化这套 Docker Jenkins Spring Boot 手动部署的组合就能稳定地为你服务很久。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑