☰
Jenkins持续集成实战:从安装配置到自动化部署的完整指南
2026/9/29 1:51:37 网站建设 项目流程

搞过几次手工部署之后,你大概率会产生一个疑问:为什么每次发版都要有人守着终端,先拉代码、再打包、再上传服务器,最后还得远程重启服务?如果哪一次漏了某个步骤,或者测试环境和生产环境的路径对不上,线上故障一出现,排查成本远高于部署本身。Jenkins就是为了解决这堆重复劳动而生的持续集成工具。我自己从最早的单机部署,到后来管理几十条流水线任务,中间踩过的坑不少,网上能搜到的教程也很多,但要么太零散,要么直接贴官方文档。这篇文章是基于我真实使用经验整理的安装配置与自动化部署实战记录,适合刚开始接触持续集成、准备把发布流程规范化的人参考,也适合已经在用但总觉得配置不得劲、想换一套更顺手的方案的人。

1. Jenkins是什么,为什么需要它

1.1 从手动发布到自动化流水线

没有持续集成工具的时候,一个标准的上线流程大概是这样的:开发本地跑测试,通过后把代码推到Git仓库,然后运维或者负责发布的人把代码拉到服务器上,执行构建命令,构建完成后把产物复制到目标目录,再重启服务。这套流程在业务简单、一天只发一次版的时候还能应付,但一旦团队人数多起来、提交频率一高,问题就暴露出来了:有人忘了拉最新代码,直接把旧版本发上去了;有人构建到一半终端关掉,服务器状态就乱了;还有人是凌晨发版,出了错还得翻聊天记录找人。

Jenkins在这个场景里扮演的角色更像一个调度中心。它负责定时或者按需执行你编排好的任务,包括拉取代码、执行构建脚本、收集测试报告、归档构建产物、触发后续的部署动作,再把结果通过邮件、钉钉或者企业微信通知给相关的人。你不需要记住每个步骤的命令,只需要把流程写进任务配置里,剩下的事情交给Jenkins去排队和分发。

1.2 Jenkins的长处和边界

Jenkins最核心的优势是插件生态。它本身是一个执行引擎,真正干活的是由各种插件扩展出来的能力。无论是拉Git仓库、执行Maven或者npm构建、连接Kubernetes集群、生成Allure测试报告,还是往钉钉群里推消息,几乎都能找到现成的插件。另一个优势是它部署简单,一个Java进程就能跑起来,不依赖外部数据库,所有配置默认都放在一个目录下面,备份和迁移都方便。

它也有不适合的场景。如果你只是需要给一个静态网站做自动发布,用GitHub Actions或者极简的脚本可能更轻量;如果你的整个技术栈都是容器化且在K8s上,ArgoCD这类面向Kubernetes原生的工具在某些场景下更合适。Jenkins的优势在于兼容性:遗留系统、老旧的服务器、各种部署协议,它都能配合起来,这也是它在企业环境里存活这么多年的原因。

2. 安装部署:三种常见方式怎么选

2.1 在线安装:war包加JDK

我最早接触Jenkins就是用war包方式,直接部署在Tomcat上。现在官方推荐的方式更加简单,直接用java -jar启动内置的Jetty服务就行,不需要单独装Tomcat。前提是装好JDK,注意版本。比较新的Jenkins版本(2.426以上的LTS版本)要求Java 11或者Java 17,我建议直接上Java 17,更稳一些,因为后面用到的许多插件对Java 17的兼容性更好。

安装步骤其实就三步。第一步,到官网下载jenkins.war包,选择LTS版本,别下载每周更新的体验版,稳定性优先。第二步,把war包放到一个独立目录,比如/opt/jenkins,然后执行:

java -jar jenkins.war --httpPort=8080

第三步,等待启动完成后,浏览器访问http://服务器IP:8080,页面会显示一个初始密码的位置,这个密码存放在/root/.jenkins/secrets/initialAdminPassword文件里,用cat命令查看并填入就行。

2.2 Docker方式部署

如果服务器上本来就跑了Docker,用容器方式部署会更省心。官方镜像jenkins/jenkins提供了LTS版本,执行命令:

docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins_home:/var/jenkins_home \ jenkins/jenkins:lts

-p 8080是Web访问端口,-p 50000是JNLP节点通信端口,-v把容器内的数据目录挂载到宿主机卷上。这里有个特别容易踩的坑:容器内的Jenkins运行用户是jenkins,UID是1000,如果宿主机挂载的目录权限不对,Jenkins启动后无法写入文件,会表现出一堆莫名其妙的权限错误。解决方法是先给挂载目录授权,比如chown -R 1000:1000 /data/jenkins_home。

2.3 离线安装怎么处理

内网环境无法访问外网是很多公司服务器的常态,这时候在线安装就走不通了。离线安装的核心是准备两样东西:war包和插件文件。war包比较好办,直接在能联网的机器上下好拷进去。插件就麻烦一点,因为Jenkins安装完成后,初始化界面默认会联网下载推荐插件。

我试过一种比较可行的离线方案:在一台同版本且联网的环境里,把$JENKINS_HOME/plugins目录下所有插件文件打包,传到内网机器的对应目录里,再启动Jenkins。前提是版本必须一致,包括插件版本,否则可能出现插件冲突。如果目标机器上还没有初始化过Jenkins,就先启动一次,让它自动生成目录结构,然后停掉服务,解压插件包再重新启动,这样能绕过初始化界面的联网下载。

2.4 安装完成验证哪些内容

启动完成后别急着配置,先花两分钟确认几个基础项。第一,日志里有没有报错,包括端口被占用、存储空间不足、权限异常;第二,访问首页能不能正常打开,初始密码能不能读到;第三,看系统监控页面,查看内存和磁盘剩余空间,Jenkins虽然不重,但构建频繁时内存占用会明显上升,内存小于2G的机器跑起来会很吃力。

3. 初始化配置:插件源、系统设置和第一个任务

3.1 插件国内源配置

完成初始安装后,第一件事就是换插件源。Jenkins默认从官方更新中心下载插件,国内网络访问速度很慢,经常下载到一半就失败。官方提供了配置升级站点的入口:系统管理→插件管理→高级→升级站点,把URL替换成国内镜像地址。比较常用的有清华源:

https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

也有用华为云的:

https://repo.huaweicloud.com/jenkins/updates/update-center.json

替换后,点一下“立即获取最新更新”,或者直接重启Jenkins让它重新加载。如果发现镜像的update-center.json里有指向默认下载服务器的URL,需要同步修改为镜像地址,否则列表能加载、安装时还是会走官方源。这个细节坑过不少人,后面第5章我会单独讲。

3.2 配置GitLab连接

代码仓库用GitLab的团队很常见。Jenkins与GitLab对接分两步:第一步,在Jenkins里添加GitLab的凭据;第二步,在系统配置里设置GitLab连接。先到GitLab用户设置里生成一个访问令牌(Access Token),权限范围勾选api和read_repository。然后在Jenkins的系统管理→凭据→系统→全局凭据里,添加一个“GitLab API Token”类型的凭据,填入这个令牌。

接着在系统管理→系统配置里,找到GitLab配置项,填写GitLab的URL,比如https://gitlab.example.com,在下方的凭据里选择刚才添加的Token,点“测试连接”。如果返回HTTP 200,就说明连接正常。配置好之后,后面创建任务时才可以接收GitLab的Webhook触发自动构建。

3.3 创建第一个自由风格任务

登录进去之后,我先建议你创建一个最简单的自由风格任务练手,而不是一上来就写Pipeline脚本。点击“新建任务”,输入名称,类型选“自由风格软件项目”,确定。源代码管理里选Git,仓库地址填项目地址,凭据选择之前配置好的用户名密码或SSH密钥。构建触发器可以先选“定时构建”,比如H/5 * * * *表示每5分钟检查一次代码变化;构建步骤里加一个“执行Shell”,写一行:

echo "hello jenkins"

保存后点击“立即构建”,看控制台输出,如果出现hello jenkins,就说明整个链路通了。这一步的意义是确认环境层面没有问题,排除代码仓库凭据错误、构建环境异常等基础故障,之后再往任务里加构建命令会顺畅很多。

4. 自动化部署实战

4.1 从简单Shell到Pipeline

自由风格任务适合简单场景,但流程一复杂,我强烈建议改用Pipeline。Pipeline把整个构建、测试、部署过程用代码的方式定义在Jenkinsfile里,好处是流程有版本记录,可以Review,不同环境之间的改动也更好追踪。最简单的声明式Pipeline是这样的:

pipeline { agent any stages { stage('拉取代码') { steps { git branch: 'main', url: 'https://gitlab.example.com/backend/app.git', credentialsId: 'gitlab-credential' } } stage('构建') { steps { sh 'mvn clean package -DskipTests' } } stage('保存产物') { steps { archiveArtifacts artifacts: 'target/*.jar', fingerprint: true } } } }

写完Jenkinsfile提交到代码仓库根目录,然后在Jenkins里新建一个“流水线”类型的任务,在定义里选择“Pipeline script from SCM”,指向这个仓库。之后每次代码提交到main分支,就可以通过Webhook触发这条流水线。

4.2 接入Allure生成测试报告

测试报告是持续集成里很容易被忽略的一块。以前我们跑完测试,结果是零散的XML文件,不聚合根本看不出问题。Allure解决的是把测试结果变成直观的HTML报告。要在Jenkins里用Allure,分别装两个插件:Allure Jenkins Plugin负责在任务里生成报告,还有一个叫Allure Commandline的全局工具,负责执行allure命令行。

安装完插件后,在系统管理→全局工具配置中,点“Allure Commandline安装”,选择从Maven仓库安装。然后回到Pipeline,在测试阶段让Maven生成Allure结果目录,一般是在target/allure-results,再在stage里加一个步骤:

stage('测试报告') { steps { allure includeProperties: false, jdk: '', report: 'target/allure-report', results: [[path: 'target/allure-results']] } }

构建完成后,任务主页的项目状态旁边会多一个“Allure Report”链接,点开就是完整的趋势图和失败用例详情。有一条经验:Allure报告的数据源是测试执行时生成的result文件,这些文件不能跨构建残留,如果发现报告里出现上一次构建的用例,多半是清理脚本没有删除target目录。

4.3 钉钉自定义消息通知

构建失败后没人知道,那自动化等于白做。我们团队用钉钉,我踩过不少钉钉通知的坑,这里给你一个比较稳的做法。先在钉钉群里添加一个自定义机器人,拿到Webhook地址,注意机器人有个安全设置,我建议用“加签”方式,比单纯IP白名单更灵活。

Jenkins里安装DingTalk插件,然后在系统配置里添加钉钉机器人,填入Webhook和加签密钥。设置完成后,可以在Pipeline里发送自定义消息:

stage('通知') { steps { dingtalk ( robot: 'jenkins-robot', type: 'ACTION_CARD', title: '构建通知', text: [ '### 构建${env.JOB_NAME}', '- 构建编号:${env.BUILD_NUMBER}', '- 构建结果:${currentBuild.currentResult}' ].join('\n'), btns: [ [ title: '查看详细日志', actionUrl: "${env.JOB_URL}console" ] ] ) } }

自定义消息的变通空间很大,你完全可以在Jenkinsfile里用sh命令写Python脚本调用Webhook,但用插件会更省事,而且扩展了加签计算、消息模板这些功能,不用自己造轮子。

4.4 上传部署包与远程发布

构建产物生成后,下一步就是发布到目标服务器。常见的做法有两种:一种是构建机也就是Jenkins所在机器直接把产物通过SSH拷到应用服务器,另一种是应用服务器主动从固定的文件服务器拉取。后者更稳定,但改动比较大,我以最常用的Publish Over SSH插件为例。

先安装Publish Over SSH插件,在系统配置里添加一台服务器:主机名、端口、认证凭据(推荐SSH私钥),设置远程目录。然后在构建步骤里选择“Send build artifacts over SSH”,配置传输的文件路径,比如target/app.jar,和目标目录/opt/app,还可以在Exec command里写远程命令:

cd /opt/app && ./restart.sh

使用密钥登录时,私钥的权限太大会被远程服务器拒绝,常见报错是Permissions 0644 for 'id_rsa' are too open,需要chmod 600。还有一个容易忽视的问题:构建机与部署机的时间不同步,会导致日志排查时时间线错乱,建议在两台机器上都配置NTP。

5. 常见问题与排查技巧

5.1 插件安装失败的几种原因

插件安装报错,排在第一的原因是网络。默认官方源在国内经常超时,换国内源能解决绝大多数情况。第二是插件依赖冲突,新旧插件对底层依赖的版本要求不一致,如果项目长期没升级,这时候“可用更新”可能有一大堆,我建议分批升,每次升完跑一遍现有流水线确认没事,再继续。

第三是缺少依赖包。有些插件之间存在依赖关系,你装的插件要求先安装另一个插件,如果不满足,日志里会给出明确的提示,去依赖对应的插件装回来就行。实在装不上的插件,可以到Jenkins官方插件站下载.hpi文件,手动放到$JENKINS_HOME/plugins目录下,重启生效。

5.2 JDK版本和工具链的坑

新版Jenkins要求Java 17,但这不意味着你构建的项目也必须用Java 17。我们的老项目还在用Java 8,这时候需要在全局工具配置里同时配置多个JDK:一个给Jenkins内部用,一个给构建任务用。在Pipeline里可以通过工具名称指定:

tools { jdk 'JDK8' maven 'Maven3' }

如果构建日志里出现UnsupportedClassVersionError,基本就是编译版本和目标运行环境版本不匹配,先检查JAVA_HOME是否正确、maven用的JDK是不是设置了。还有一点,不要在构建步骤里随意export JAVA_HOME,除非你真的清楚自己在改什么,否则会覆盖全局配置导致不可预知的问题。

5.3 update-center.json和升级站点镜像问题

很多人在换国内源之后还是下载慢,排查方向要放在update-center.json是否真正生效。Jenkins读取这个文件后,里面每一项插件记录中都有一个url字段,指向实际的下载地址。国内镜像如果只改了页面入口、没有同步修正字段,最后下载还是走官方服务器。

一个快速判断方法:打开系统管理→插件管理→高级,查看升级站点URL,如果显示的是清华或华为的地址,再看看可用插件列表能不能正常加载。如果列表能加载,但点安装就卡住或失败,大概率就是下载地址没有替换完全。可以手动下载镜像上对应的.hpi文件,放进plugins目录,重启后解决。升级Jenkins版本前也一样,先备份整个$JENKINS_HOME目录,再换war包或者镜像标签。

5.4 关于Jenkins MCP的补充

最近有一个新的方向值得关注,就是Jenkins MCP(Model Context Protocol)。简单来说,它让AI模型可以通过标准协议读取Jenkins上的任务状态、构建日志,并进行触发或构建操作。如果你在用Cursor、Claude等支持MCP的AI开发环境,可以配置Jenkins的MCP Server,让AI帮你查看构建失败原因。这个功能对日常排查确实有帮助,但目前还比较新,我建议先在测试环境体验,别急着部署到生产流水线里。

结尾

Jenkins的安装使用,说到底就是一个把可重复的事情标准化的过程。我个人的经验是,不要一开始就追求完美的平台结构,先跑通一条最简单的构建链路,确认代码拉取、构建、存档、通知都正常,再逐步加东西:加测试报告、加远程部署、加多分支流水线。每一次改动后都要跑一遍现有任务,确认没弄坏旧功能。至于那些文档里不会写、只有踩坑后才能知道的小细节,比如国内源要换彻底、插件升级要分批、远程服务器密钥权限要正确,这些往往才是真正影响使用体验的地方。如果你也在搭Jenkins,建议先把这套最小闭环搭出来,用起来之后再迭代,方向不会错。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询