引言:部署 Jenkins 之前
在若依项目的治理系列中,我们已经完成了用户体系构建、权限管控、LVM存储规划和日志分析体系——目录有归属了,权限有边界了,日志有可追溯性了。这时候,一个顺理成章的问题浮出水面:谁来负责持续集成?谁来把若依项目的代码自动构建、自动部署?
Jenkins正是回答这个问题的工具。
一、为什么 Jenkins 需要“被治理”?
很多人在部署 Jenkins 时,往往只关注"怎么让它跑起来”,而忽略了另一个同样重要的问题:它要跑多久?怎么让它持续跑?
前台运行java -jar jenkins.war确实能启动 Jenkins,但问题也接踵而至:
| 运行方式 | 是否持久 | 是否自愈 | 是否可控 |
|---|---|---|---|
java -jar前台 | ❌ 关闭终端即停 | ❌ 崩溃即死 | ❌ 需手动重来 |
nohup ... &后台 | ✅ 可后台运行 | ❌ 崩溃即死 | ⚠️ 难管理 |
| Systemd 服务 | ✅ 开机自启 | ✅ 自动重启 | ✅ 统一管理 |
在前面的若依项目治理中,我们已经用 Systemd 管理了 Nginx 和 MariaDB。Jenkins 也应该享有同样的“待遇”——它不是一次性的任务,而是持续的自动化基础设施。
部署 Jenkins 的方式,决定了它成为“工具”还是“负担”。
二、环境准备:Java 是第一道门槛
Jenkins 是用 Java 编写的,所以部署 Jenkins 的第一步永远是安装 Java。
2.1 安装 JDK 25
杨哥提示:Jenkins 需要 JDK 11 或更高版本。在 Rocky Linux 上,我们统一使用 JDK 25。
[root@magedu ~]# dnf install -y java-25-openjdk-headless验证安装:
[root@magedu ~]# java -version openjdk version "25.0.3" 2026-04-21 LTS OpenJDK Runtime Environment (Red_Hat-25.0.3.0.9-1) (build 25.0.3+9-LTS) OpenJDK 64-Bit Server VM (Red_Hat-25.0.3.0.9-1) (build 25.0.3+9-LTS, mixed mode, sharing)2.2 一个容易被忽略的问题:字体
如果使用 Rocky Linux 最小化安装,启动 Jenkins 时可能会遇到这个错误:
java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration这是因为 Jenkins 的 Web UI 需要渲染字体,而最小化安装没有字体包。
解决方法:
dnf install -y fontconfig dejavu-sans-fonts dejavu-serif-fonts三、下载 Jenkins:镜像源的选择
# 创建目录 [root@magedu ~]# mkdir -p /opt/jenkins # 下载(清华镜像源,速度快) [root@magedu ~]# wget -O /opt/jenkins/jenkins.war https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war为什么用清华镜像源?因为 Jenkins 官方下载速度不稳定,而国内的镜像站提供了稳定的加速通道。
四、演示一:直接启动(Java -jar)
[root@magedu ~]# cd /opt/jenkins [root@magedu ~]# java -jar jenkins.war启动后,浏览器访问http://服务器IP:8080,看到 Jenkins 解锁页面说明启动成功。
初始密码获取:
[root@magedu ~]# cat /root/.jenkins/secrets/initialAdminPassword 0ba21e9c86cb470d8daff75ded044ece优缺点分析:
| 优点 | 缺点 |
|---|---|
| 快速验证 | 关闭终端即停止 |
| 适合测试 | 无法开机自启 |
| 调试方便 | 崩溃无人管 |
五、演示二:Systemd 服务——把 Jenkins 变成“基础设施”
如果 Jenkins 只用于临时测试,java -jar就够了。但如果 Jenkins 要作为若依项目持续集成的核心工具,就必须把它变成可管理、可自愈的系统服务。
5.1 创建服务文件
[root@magedu ~]# vim /etc/systemd/system/jenkins.service填入以下内容:
[Unit] Description=Jenkins Continuous Integration Server After=network.target [Service] Type=simple User=root Group=root WorkingDirectory=/opt/jenkins ExecStart=/usr/bin/java -jar /opt/jenkins/jenkins.war Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target各部分说明:
| 部分 | 参数 | 含义 |
|---|---|---|
| [Unit] | Description | 服务描述 |
| [Unit] | After=network.target | 网络就绪后再启动 |
| [Service] | Type=simple | 默认类型,主进程就是服务进程 |
| [Service] | WorkingDirectory | 工作目录 |
| [Service] | ExecStart | 启动命令 |
| [Service] | Restart=on-failure | 崩溃后自动重启 |
| [Service] | RestartSec=10 | 重启前等待10秒 |
| [Install] | WantedBy=multi-user.target | 开机自启 |
5.2 启动并验证
# 重新加载 systemd 配置 [root@magedu ~]# systemctl daemon-reload # 启动服务 [root@magedu ~]# systemctl start jenkins # 开机自启 [root@magedu ~]# systemctl enable jenkins # 查看状态 [root@magedu ~]# systemctl status jenkins.service状态输出示例:
● jenkins.service - Jenkins Continuous Integration Server Loaded: loaded (/etc/systemd/system/jenkins.service; enabled) Active: active (running) since Thu 2026-07-23 02:28:32 CST; 14s ago Main PID: 4394 (java) Memory: 138.7M CGroup: /system.slice/jenkins.service └─4394 /usr/bin/java -jar /opt/jenkins/jenkins.war5.3 防火墙配置
# 开放端口 [root@magedu ~]# firewall-cmd --permanent --add-port=8080/tcp success [root@magedu ~]# firewall-cmd --reload success # 确认已开放 [root@magedu ~]# firewall-cmd --permanent --list-all ports: 8080/tcp六、演示三:崩溃自动重启(Restart=on-failure 实战)
Systemd 的Restart=on-failure可以让 Jenkins 在崩溃时自动恢复。
6.1 验证服务正在运行
[root@magedu ~]# systemctl status jenkins.service ● jenkins.service - Jenkins Continuous Integration Server Active: active (running) since Thu 2026-07-23 02:28:32 CST; 5min ago6.2 获取进程 PID
[root@magedu ~]# ps aux | grep jenkins.war | grep -v grep root 4394 2.3 11.3 3802996 420072 ? Ssl 02:28 0:09 /usr/bin/java -jar /opt/jenkins/jenkins.war6.3 模拟崩溃
[root@magedu ~]# kill -9 43946.4 查看自动恢复
等待几秒后再次查看状态:
[root@magedu ~]# systemctl status jenkins.service ● jenkins.service - Jenkins Continuous Integration Server Active: active (running) since Thu 2026-07-23 02:35:30 CST; 3s ago Main PID: 4709 (java) Memory: 141.3M关键结论:kill -9强制杀死了 Jenkins 进程,但 systemd 在 10 秒后自动启动了一个新的 Jenkins 进程(PID 从 4394 变为 4709)。
在生产环境中,这种自动恢复能力意味着:即使 Jenkins 因内存溢出或意外崩溃而退出,系统也会自动拉起它,无需人工介入。
七、从 Java -Jar 到 Systemd:治理逻辑的延续
回顾若依项目治理系列的核心脉络,Jenkins 的部署方式变化不是技术升级,而是治理思维的延展。
| 治理阶段 | 核心内容 | Jenkins 对应操作 |
|---|---|---|
| 用户治理 | 告别共用 root | Jenkins 进程以 root 运行 |
| 端口管控 | 防火墙开放端口 | firewall-cmd --add-port=8080/tcp |
| 目录治理 | /opt/ruoyi标准化 | /opt/jenkins作为安装目录 |
| 服务治理 | Nginx/MySQL 用 Systemd 管理 | Jenkins 用 Systemd 管理 |
| 自愈能力 | 服务异常自动恢复 | Restart=on-failure |
| 可观测性 | 日志可追溯 | systemctl status+journalctl |
核心思路一致:把 Jenkins 从“手动运行的一次性工具”变成“可管理、可自愈、可追溯的系统服务”。
八、故障排查速查
| 问题 | 检查方法 | 解决方案 |
|---|---|---|
| 启动失败 | systemctl status jenkins | journalctl -u jenkins -n 50 |
| 端口被占用 | `netstat -tlnp | grep 8080` |
| 字体缺失 | java -jar报 Fontconfig 错误 | dnf install fontconfig dejavu-sans-fonts |
| 防火墙未放行 | curl localhost:8080失败 | firewall-cmd --add-port=8080/tcp |
| 初始密码找不到 | cat报错 | 确认 Jenkins 已启动,等待几秒再试 |
九、总结
Jenkins 的部署看似简单,但部署方式的选择决定了它在生产环境中的可靠性。通过 systemd 服务化部署,我们实现了:
- 持久化运行:开机自启,终端关闭不影响
- 自动恢复:进程崩溃后自动重启
- 统一管理:与系统其他服务统一管理
- 可观测性:通过 systemd 工具链监控状态。
这正是若依项目治理系列的核心思想:将临时工具转变为可持续的基础设施。Jenkins 作为持续集成的核心,值得这样的“待遇”。
三条核心结论
部署方式决定工具属性。
java -jar让 Jenkins 成为“运行一次的工具”,Systemd 让 Jenkins 成为“长期服役的基础设施”。若依项目需要的是后者。治理是可复用的方法论。若依项目目录用 750 保护配置,防火墙用
--add-port开放端口,服务用systemctl统一管理——这些操作不仅适用于若依,同样适用于 Jenkins。治理不是一次性工程,而是一套可复用的标准化动作。Restart=on-failure 是最低成本的运维保障。Systemd 的自动重启机制,是生产环境服务治理的基石。它不需要写任何监控脚本,不需要额外部署告警系统,仅仅是三行配置(
Restart=on-failure、RestartSec=10),就能实现崩溃自动恢复。这是性价比最高的运维投入。
标准化的目录是骨骼,安全的权限是肌肉,日志与审计是神经系统——而 Systemd 服务治理,则是让 Jenkins 这条持续集成的"生产线"能够稳定运行的关节。
当 Jenkins 成为 Systemd 服务后,它不仅有了“家”(/opt/jenkins),有了“门禁”(防火墙端口),有了“健康检查”(systemctl status),还有了“自愈能力”(Restart=on-failure)——它不再是孤立的工具,而是融入若依项目治理体系的基础设施组件。
本文是"若依项目Linux生产环境治理"系列之 Jenkins 部署篇。系列其他文章覆盖用户权限治理、目录结构规范化、sudo 精细化权限管控、LVM 存储管理、日志分析与正则实战等内容,构建了一套从底层存储到上层应用的完整治理方法论,欢迎关注。