Jenkins 2.346.1 内网离线安装插件:依赖解析与版本匹配实战
简介本资源面向在内网、隔离网等无外网环境中部署Jenkins的运维与DevOps工程师针对Jenkins 2.346.1无法在线拉取插件的问题提供一套完整的离线插件安装方案。压缩包共约2000个文件整体314.4MB涵盖90个jpi与30个hpi插件包、366个jar依赖、192个xml配置及大量js、html、css等前端资源并附带properties、timestamp等元数据文件构成可直接落地的离线插件仓库。资源围绕离线下载插件、创建离线插件包、配置初始化脚本、启动验证、后续维护更新与安全权限控制等环节展开帮助读者打通内网Jenkins插件安装全流程。目前已有3171人学习下载适合需要快速搭建内网CI/CD环境、排查插件加载失败问题的技术人员参考可有效减少重复试错成本。1. 内网 Jenkins 离线装插件为什么 2.346.1 的插件包不能随便下很多团队的内网构建机跑着 Jenkins 2.346.1版本不算新但胜在稳定谁也不想动它。问题出在装插件上外网能访问的更新中心内网机器一个字节都拉不到点「安装」就是转圈然后报错。有人图省事从别的机器把.hpi拷过来直接丢进plugins目录重启后插件列表里是有了但构建任务一跑就抛NoSuchMethodError查半天才发现是插件版本和 Jenkins 核心对不上。这个场景要解决的核心问题就一句话在没有外网的内网环境里给 Jenkins 2.346.1 装上一批能正常工作的插件。适合两类人一是负责内网 CI 环境维护、被离线安装折腾过的运维二是需要在隔离网络里搭一套完整构建流水线的开发。下面按「先搞懂依赖关系再动手下载最后排错」的顺序拆开讲每一步都能直接抄。2. 离线安装的底层逻辑插件依赖树与版本匹配2.1 为什么不能只下单个 .hpi 文件Jenkins 插件不是孤立运行的。一个插件会声明它依赖哪些其他插件、依赖的最低版本是多少这些信息写在插件元数据里。你只下git.hpi它可能依赖git-client、credentials、structs等一串插件缺一个就装不上或者装上了运行时报错。常见做法是先确定你要装的目标插件然后递归解析它的依赖树把所有依赖插件连同目标插件一起下载。手动做这件事很容易漏所以一般用工具自动解析。版本匹配是第二个关键点。Jenkins 2.346.1 对应的插件更新中心有它自己的版本范围同一个插件在 2.346.1 和 2.4xx 上能用的版本可能不同。判断依据是插件页面上的「Required Core」字段它标明了这个插件版本要求的最低 Jenkins 核心版本。你选的插件版本Required Core 必须小于等于 2.346.1。2.2 依赖解析的两种可行路径路径一用官方更新中心的数据做离线解析。Jenkins 更新中心有一个update-center.json里面记录了每个插件的所有版本、依赖关系和 Required Core。你可以在外网机器上拉这个文件用脚本解析出目标插件的完整依赖树再按版本约束筛选出适配 2.346.1 的版本组合。路径二用现成的离线下载工具。社区里有针对 Jenkins 的插件下载脚本输入插件名和 Jenkins 版本输出一个包含所有依赖的目录。这类工具的原理和路径一一样只是把解析逻辑封装好了。我一般会走路径一因为可控。下面给一个用 Python 解析依赖树的骨架代码核心是从update-center.json里递归找依赖。import json import requests # 从外网机器拉取更新中心数据内网机器提前拷贝好这个文件 # 注意不同 Jenkins 版本的更新中心 URL 不同2.346.1 对应的是稳定版更新中心 UPDATE_CENTER_URL https://updates.jenkins.io/stable/update-center.json def load_update_center(local_pathNone): 加载更新中心数据支持本地文件或在线拉取 if local_path: with open(local_path, r, encodingutf-8) as f: raw f.read() else: raw requests.get(UPDATE_CENTER_URL).text # update-center.json 外层包了一层 JSONP 回调需要剥掉 raw raw.strip() if raw.startswith(updateCenter.post(): raw raw[len(updateCenter.post():] if raw.endswith();): raw raw[:-2] return json.loads(raw) def resolve_deps(uc_data, plugin_name, jenkins_version, resolvedNone): 递归解析插件依赖返回 {插件名: 版本} 的字典 if resolved is None: resolved {} if plugin_name in resolved: return resolved plugins uc_data[plugins] if plugin_name not in plugins: raise ValueError(f插件 {plugin_name} 不在更新中心数据里) info plugins[plugin_name] # 筛选出 Required Core 当前 Jenkins 版本的版本 candidates [] for ver, meta in info.items(): if ver name: continue required_core meta.get(requiredCore, 0) if compare_version(required_core, jenkins_version) 0: candidates.append((ver, meta)) if not candidates: raise ValueError(f{plugin_name} 没有适配 {jenkins_version} 的版本) # 取满足条件的最高版本 candidates.sort(keylambda x: x[0], reverseTrue) chosen_ver, chosen_meta candidates[0] resolved[plugin_name] chosen_ver # 递归处理依赖 for dep_name, dep_ver in chosen_meta.get(dependencies, {}).items(): resolve_deps(uc_data, dep_name, jenkins_version, resolved) return resolved def compare_version(v1, v2): 简单的版本号比较返回 -1/0/1 parts1 [int(x) for x in v1.split(.) if x.isdigit()] parts2 [int(x) for x in v2.split(.) if x.isdigit()] for a, b in zip(parts1, parts2): if a b: return -1 if a b: return 1 return 0这段代码的逻辑说明load_update_center负责把更新中心数据读进来注意它外层有 JSONP 包装直接json.loads会失败必须先剥壳。resolve_deps是核心递归函数它先按requiredCore过滤出适配当前 Jenkins 版本的插件版本取最高版本后再遍历这个版本的dependencies字段继续递归。compare_version是个简化版比较函数实际用的时候建议换成packaging.version库避免遇到1.10和1.9比较出错。参数方面jenkins_version传2.346.1plugin_name传你要装的目标插件名比如git。跑完之后resolved字典里就是完整的插件名和版本列表。2.3 下载环节的目录组织解析出依赖列表后下载环节要按固定结构组织文件方便后续批量安装。我一般用这样的目录offline-plugins/ ├── download_list.txt # 插件名:版本 列表 ├── hpi/ # 所有 .hpi 文件 │ ├── git-4.11.3.hpi │ ├── git-client-3.11.0.hpi │ └── ... └── install.sh # 批量安装脚本下载 URL 的规律是https://updates.jenkins.io/download/plugins/{插件名}/{版本}/{插件名}.hpi。注意文件名里不带版本号版本号在路径里。下载脚本按这个规律拼 URL 即可。3. 内网落地实操从外网下载到 Jenkins 加载3.1 外网机器上的下载与打包在外网机器上先跑上面的解析脚本拿到依赖列表然后批量下载。下面是一个下载脚本读download_list.txt逐行下载。#!/bin/bash # 在外网机器上执行下载所有插件到 hpi 目录 set -e DOWNLOAD_DIR./hpi LIST_FILE./download_list.txt BASE_URLhttps://updates.jenkins.io/download/plugins mkdir -p $DOWNLOAD_DIR while IFS: read -r name version; do # 跳过空行和注释 [[ -z $name || $name \#* ]] continue url${BASE_URL}/${name}/${version}/${name}.hpi out${DOWNLOAD_DIR}/${name}-${version}.hpi if [[ -f $out ]]; then echo 已存在跳过: $out continue fi echo 下载: $url curl -fSL -o $out $url done $LIST_FILE echo 下载完成共 $(ls -1 $DOWNLOAD_DIR | wc -l) 个文件逻辑说明IFS:按冒号分割每行因为download_list.txt的格式是插件名:版本。curl -fSL里-f让 HTTP 错误码直接失败而不是写入错误页面-L跟随重定向-S显示错误。下载完成后检查文件数量是否和列表行数一致不一致说明有下载失败。打包时把hpi目录和install.sh一起打成 tar 包通过内网允许的方式传到目标机器。注意不要用zip因为 Jenkins 机器上不一定有解压工具tar更通用。3.2 内网机器上的批量安装传到内网后有两种安装方式。方式一是直接拷贝到JENKINS_HOME/plugins目录然后重启。方式二是用 Jenkins CLI 的install-plugin命令。方式一更直接但要注意权限和文件属主。#!/bin/bash # 在内网 Jenkins 机器上执行 set -e JENKINS_HOME/var/lib/jenkins # 按实际路径改 HPI_DIR./hpi # 备份现有插件目录出问题能回滚 BACKUP_DIR${JENKINS_HOME}/plugins.bak.$(date %Y%m%d%H%M%S) cp -a ${JENKINS_HOME}/plugins $BACKUP_DIR echo 已备份到 $BACKUP_DIR # 拷贝新插件注意属主 cp -v ${HPI_DIR}/*.hpi ${JENKINS_HOME}/plugins/ chown -R jenkins:jenkins ${JENKINS_HOME}/plugins # 删除插件解压缓存强制重新解压 find ${JENKINS_HOME}/plugins -maxdepth 1 -type d -name *.hpi -prune -o -type d -print | while read d; do # 只删和 hpi 同名的解压目录 base$(basename $d) if [[ -f ${JENKINS_HOME}/plugins/${base}.hpi ]]; then rm -rf $d fi done echo 插件拷贝完成请重启 Jenkins逻辑说明先备份是血泪经验插件装崩了能直接回滚。chown必须做否则 Jenkins 进程读不到文件。删除解压缓存这一步很多人会漏Jenkins 加载插件时如果发现同名目录已存在可能不会重新解压新的.hpi导致你以为装了新版本实际还是旧的。重启命令按你的部署方式选systemctl restart jenkins或service jenkins restart。重启后看日志确认加载情况。3.3 验证插件是否真正生效重启不等于装好。验证分三步第一步看 Jenkins 启动日志里有没有插件加载失败的报错第二步进「系统管理 → 插件管理 → 已安装」看插件是否在列表里且版本正确第三步实际跑一个用到该插件的构建任务。# 查看启动日志中的插件加载错误 grep -i failed to load\|SEVERE.*plugin\|Plugin.*failed /var/log/jenkins/jenkins.log | tail -50 # 查看已加载插件列表通过 Jenkins CLI java -jar jenkins-cli.jar -s http://localhost:8080/ -auth admin:token list-plugins | grep -i git日志里如果出现Failed to load: xxx (xxx)后面跟NoClassDefFoundError或NoSuchMethodError基本就是版本不匹配。list-plugins命令需要 Jenkins CLI 的 jar 包和认证信息认证用 API Token 比密码安全。4. 避坑与排查离线装插件最容易翻车的五个点4.1 现象插件列表里有了但构建时报 NoSuchMethodError原因插件版本和 Jenkins 核心版本不匹配。你下载的插件版本 Required Core 高于 2.346.1Jenkins 加载时没拦住但运行时调用了核心不存在的方法。解决回到更新中心数据重新按requiredCore 2.346.1筛选版本。不要只看插件的最新版最新版往往要求更高的核心版本。4.2 现象重启后插件消失或者版本没变原因Jenkins 的插件加载机制会优先读解压后的目录如果同名目录已存在它不会重新解压新的.hpi。你拷贝了新文件但旧目录还在加载的还是旧版本。解决拷贝新.hpi后删除对应的解压目录再重启。上面的安装脚本里已经包含这一步。更稳妥的做法是停掉 Jenkins 再操作避免运行中文件被占用。4.3 现象插件装上了但功能不可用比如 Git 插件找不到 git 命令原因插件本身是 Jenkins 侧的封装它依赖系统里安装的 git 可执行文件。离线环境里 Jenkins 机器可能没装 git或者 git 路径不在 Jenkins 进程的 PATH 里。解决在 Jenkins 的「系统管理 → 全局工具配置」里显式指定 git 路径不要依赖 PATH。同时确认jenkins用户能执行git --version。4.4 现象依赖插件缺失安装时报「依赖未满足」原因解析依赖树时漏了传递依赖或者某个依赖插件的版本被其他插件约束到了不兼容的范围。解决用resolve_deps跑完整依赖树不要手动挑。如果两个插件对同一个依赖的版本要求冲突优先满足 Required Core 更高的那个插件的约束然后验证另一个插件是否还能工作。4.5 现象拷贝文件后 Jenkins 启动失败日志报权限错误原因cp操作是以当前用户执行的文件属主不是jenkinsJenkins 进程读不到。解决chown -R jenkins:jenkins整个 plugins 目录。另外注意JENKINS_HOME的父目录权限如果 Jenkins 用户对父目录没有执行权限一样读不到。提示每次批量装插件前先备份plugins目录和config.xml。回滚成本远低于排查成本。5. 进阶技巧用脚本做版本校验和增量更新装完一批插件后后续维护的痛点在于怎么知道哪些插件有新版本、新版本是否适配当前 Jenkins。我一般会写一个校验脚本把内网已装插件列表和外网更新中心数据做比对输出可升级列表和对应的 Required Core。import json def check_updates(uc_data, installed, jenkins_version): 比对已装插件和更新中心输出可升级且适配的插件 plugins uc_data[plugins] result [] for name, current_ver in installed.items(): if name not in plugins: continue candidates [] for ver, meta in plugins[name].items(): if ver name: continue if compare_version(meta.get(requiredCore, 0), jenkins_version) 0: candidates.append(ver) if not candidates: continue candidates.sort(keylambda v: [int(x) for x in v.split(.) if x.isdigit()], reverseTrue) latest candidates[-1] if compare_version(latest, current_ver) 0: result.append((name, current_ver, latest)) return result # installed 从 Jenkins 的 plugins 目录或 list-plugins 输出解析得到 # 输出格式[(插件名, 当前版本, 可升级版本), ...]这个脚本的价值在于它不会推荐 Required Core 超过当前 Jenkins 版本的升级避免你升完发现 Jenkins 起不来。installed字典可以从JENKINS_HOME/plugins目录下的.hpi文件名解析也可以用list-plugins命令的输出。增量更新的操作流程是跑校验脚本拿到可升级列表只下载这些插件的.hpi传到内网后按第 3 章的安装脚本替换。注意替换前仍然要备份并且删除对应的解压目录。还有一个容易被忽略的点Jenkins 的插件更新中心数据本身会变同一个插件版本在不同时间拉到的update-center.json可能不同。所以在外网下载时建议把update-center.json一起打包传到内网后续排查版本问题时能对照当时的数据。从那以后我每次做离线插件安装都强制走一遍「解析依赖 → 下载 → 备份 → 拷贝 → 删缓存 → 重启 → 验证」这七步少一步都可能翻车。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

PgDog 配置 crate 的文档注释规范:一份注释同时驱动 Rustdoc 与 JSON Schema

PgDog 配置 crate 的文档注释规范:一份注释同时驱动 Rustdoc 与 JSON Schema

数据库后端 【免费下载链接】pgdog PostgreSQL connection pooler, load balancer and database sharder. 项目地址: https://gitcode.com/gh_mirrors/pg/pgdog 点击查看 免费下载 PgDog 是一个用 Rust 编写的 PostgreSQL 连接池、负载均衡与分库分表中间件&#x…

2026/10/12 2:05:08 阅读更多 →
Learn to Cloud 阶段一:SSH 安全远程接入云端虚拟机——从密钥原理到三大云厂商实操

Learn to Cloud 阶段一:SSH 安全远程接入云端虚拟机——从密钥原理到三大云厂商实操

教程云原生 【免费下载链接】learn-to-cloud A courseware built on the belief that anyone can learn foundational cloud engineering skills with the right guide and discipline 项目地址: https://gitcode.com/gh_mirrors/le/learn-to-cloud 点击查看 免费下…

2026/10/12 2:05:08 阅读更多 →
DeepSeek职场赋能实战:四段式提示词模板与工作流嵌入指南

DeepSeek职场赋能实战:四段式提示词模板与工作流嵌入指南

简介:这份PDF资料是清华大学DeepSeek系列讲座第二讲,共35页,面向希望将大模型落地于职场场景的技术人员、产品经理与管理者。内容围绕DeepSeek职场赋能展开,提出Organization、Innovator、Reasoner、Chatbot四层应用框架&#xff…

2026/10/12 2:05:08 阅读更多 →

最新新闻

嵌入式Linux安卓驱动开发:供需、实战与面试全攻略

嵌入式Linux安卓驱动开发:供需、实战与面试全攻略

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

2026/10/12 2:53:39 阅读更多 →
共享Buffer却带宽没降?DDR流量的五大根因与排查实战

共享Buffer却带宽没降?DDR流量的五大根因与排查实战

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

2026/10/12 2:53:39 阅读更多 →
OTFS信道估计实战:压缩感知与相位旋转在高速移动通信中的应用

OTFS信道估计实战:压缩感知与相位旋转在高速移动通信中的应用

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

2026/10/12 2:53:39 阅读更多 →
Qt5.9 C++开发指南章节代码实战:从环境搭建到工程避坑

Qt5.9 C++开发指南章节代码实战:从环境搭建到工程避坑

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

2026/10/12 2:53:39 阅读更多 →
Linux进程虚拟地址空间:从页表映射到段错误排查

Linux进程虚拟地址空间:从页表映射到段错误排查

搞Linux服务端开发的人,迟早会遇到这么一幕:程序跑着跑着突然Segmentation Fault,或者free的时候报double free,又或者top里看到某个进程的VIRT高得离谱,但RES却很低。很多人第一反应是查代码、查日志,但真…

2026/10/12 2:53:39 阅读更多 →
ESP32 上实现 ONVIF 相机:从组件搭建到 NVR 添加实战

ESP32 上实现 ONVIF 相机:从组件搭建到 NVR 添加实战

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

2026/10/12 2:52:39 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/11 14:36:54 阅读更多 →