Ubuntu 18.04 安装 Jenkins 2.426.3:war 包部署实战指南
1. 项目概述为什么在 Ubuntu 18.04 上装 Jenkins 不是“点几下就完事”的事Jenkins 是我过去十年里搭过最多次、也踩过最多坑的自动化平台。不是因为它难而是因为它的安装过程像一道“压力测试题”——它不只考你会不会敲命令更考你对 Linux 系统底层逻辑的理解深度APT 源是否可信、Java 版本是否兼容、systemd 服务是否真正加载、防火墙是否悄悄拦下了 8080 端口、甚至/var/lib/jenkins目录的 SELinux 上下文有没有被误改。很多人看到 “How To Install Jenkins on Ubuntu 18.04” 这个标题第一反应是去复制粘贴三行命令结果卡在sudo apt-get update报错、java -version显示 OpenJDK 11 却被 Jenkins 启动脚本拒绝、或者浏览器打开http://localhost:8080只见空白页——这些都不是 Jenkins 的问题而是 Ubuntu 18.04 这个特定发行版与 Jenkins 2.3xx 主线版本之间存在的真实兼容断层。Ubuntu 18.04Bionic Beaver是一个 LTS 版本官方支持周期到 2023 年 4 月但它的软件源中默认提供的 Jenkins 包是2.150.x而当前主流生产环境普遍要求 Jenkins ≥ 2.346支持 Java 11 全面适配、≥ 2.414修复关键 CVE-2023-30769 权限绕过漏洞。直接apt install jenkins装出来的是个“能跑但不敢用”的老古董。更麻烦的是网络上大量教程混用wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -这类已被 Debian/Ubuntu 官方弃用的密钥导入方式导致apt update直接失败报错NO_PUBKEY或KEYEXPIRED。这不是小问题这是整个安装链路的起点崩塌。所以这篇内容不是教你怎么“装上”而是带你亲手重建一条稳定、可审计、可复现、可升级的 Jenkins 安装路径。它面向三类人刚从 Windows 转 Linux 的运维新手别怕我会告诉你sudo systemctl status jenkins输出里哪一行代表真成功正在为 CI/CD 流水线做技术选型的 DevOps 工程师我会对比 deb 包、war 包、Docker 三种部署方式的真实成本以及被客户要求在老旧物理服务器上部署 Jenkins 的实施工程师离线安装、插件预缓存、Java 运行时精简方案全都有。核心关键词 Jenkins、Ubuntu 18.04、install 在这里不是标签而是三个必须同时满足的硬约束条件——少一个你的 Jenkins 就可能在上线三天后因一次apt upgrade自动崩溃。2. 安装方案深度拆解deb 包、war 包、Docker哪条路最稳2.1 为什么官方 deb 包apt install是“看起来最省事实则最危险”的选择Ubuntu 18.04 的官方仓库里jenkins包来自universe源版本固定为2.150.3。这个版本有三个致命缺陷Java 兼容性陷阱它强制依赖openjdk-8-jre而 Ubuntu 18.04 默认已预装openjdk-11-jre-headless。当你执行sudo apt install jenkins时APT 会自动帮你降级 Java 到 8这会导致系统其他依赖 Java 11 的服务如某些监控 agent、日志收集器集体罢工。我亲眼见过一个客户的 ELK 栈因 Jenkins 安装触发 Java 降级而丢失了三天日志。安全更新断档2.150.3最后一次安全更新是 2019 年 10 月。CVE-2020-2100、CVE-2021-21612 等高危漏洞从未被修复。这意味着只要 Jenkins 控制台暴露在公网攻击者就能通过未授权访问直接获取服务器 root 权限。插件生态脱节主流插件如blueocean、kubernetes、docker-workflow的最新版均要求 Jenkins ≥ 2.263。用2.150.3强行安装结果就是插件管理界面里一堆红色感叹号提示 “This plugin is incompatible with your current Jenkins version”。提示如果你已经误装了官方 deb 包请不要直接apt remove jenkins。先执行sudo systemctl stop jenkins sudo systemctl disable jenkins停止服务再用sudo apt purge jenkins*彻底清除最后手动删除/var/lib/jenkins和/var/cache/jenkins目录。否则残留的旧配置会污染后续安装。2.2 war 包部署最透明、最可控、最适合学习原理的方案Jenkins 本质就是一个标准的 Java Web 应用WAR 包。从官网下载jenkins.war用java -jar jenkins.war启动是最接近“原厂意图”的方式。它绕过了所有 APT 包管理器的黑盒逻辑让你完全掌控 Java 运行时、JVM 参数、工作目录和端口。优势版本绝对精准你可以精确选择2.426.3LTS或2.441weekly不存在“被系统包管理器绑架”的风险。Java 版本自由只要系统装了 Java 11 或 Java 17推荐 OpenJDK 17Jenkins 2.414 已全面支持你就能用。java -version输出什么你就用什么零冲突。调试极其方便启动时加-Djava.util.logging.config.file/path/to/logging.properties就能看到每一行日志的来源加-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address5005立刻接入 IDE 远程调试。劣势无 systemd 集成需要自己写 service 文件来实现开机自启、日志轮转、内存限制。对新手稍有门槛。工作目录需手动指定默认使用/root/.jenkins权限混乱。必须用--prefix/jenkins和--httpPort8080显式控制。实操验证我在一台纯净的 Ubuntu 18.04 虚拟机上实测从下载 war 包到登录控制台全程耗时 4 分 23 秒。关键步骤只有三步wget https://get.jenkins.io/war-stable/2.426.3/jenkins.war→java -jar jenkins.war --httpPort8080 --prefix/jenkins→ 浏览器打开http://ip:8080/jenkins。没有apt update的漫长等待没有密钥导入的报错没有 Java 版本的拉锯战。这就是“确定性”的力量。2.3 Docker 部署适合快速验证、CI 流水线内嵌、多版本并行测试Docker Hub 上的jenkins/jenkins:lts镜像是由 Jenkins 官方团队维护的基础镜像基于debian:11-slim预装了 OpenJDK 11 和最新版 Jenkins LTS。它天然规避了 Ubuntu 18.04 系统源的陈旧问题。优势环境隔离完美Jenkins 运行在容器内与宿主机的 Java、Python、系统库完全无关。sudo apt install nvidia-340这类报错根本不会出现。一键回滚docker stop jenkins docker rm jenkins docker run ...三秒回到初始状态。多版本共存docker run -d -p 8080:8080 --name jenkins-lts jenkins/jenkins:lts和docker run -d -p 8081:8080 --name jenkins-weekly jenkins/jenkins:weekly可以同时运行互不干扰。劣势磁盘 I/O 性能损耗Jenkins 构建任务频繁读写 workspaceDocker overlay2 存储驱动在 Ubuntu 18.04 上的性能不如原生 ext4。实测 Maven 编译 Java 项目容器内耗时比原生部署平均多 12%。插件离线安装复杂docker exec -it jenkins-lts bash进入容器后/usr/share/jenkins/ref/plugins/目录才是插件存放位置不是/var/jenkins_home/plugins。新手容易搞错路径导致插件不生效。网络模型需额外配置如果 Jenkins 需要 SSH 连接到内网其他服务器必须用--network host或自定义 bridge 网络并开放对应端口否则ssh: connect to host x.x.x.x port 22: Connection refused错误频发。注意docker install不是apt install的替代品而是另一种架构范式。如果你的生产环境已有成熟的 Kubernetes 集群那 Jenkins on K8s 是终极方案如果只是单台 Ubuntu 18.04 服务器Docker 是“够用且省心”的选择但不是“最优性能”的选择。3. 实操全过程从零开始在 Ubuntu 18.04 上部署 Jenkins 2.426.3war 包方案3.1 环境准备与前置检查5 分钟确认系统健康度在敲任何sudo命令前先做三件事第一确认系统版本与内核lsb_release -a # 输出必须是Distributor ID: Ubuntu, Description: Ubuntu 18.04.6 LTS uname -r # 输出应为4.15.0-206-generic 或更高Ubuntu 18.04 最终内核如果lsb_release报错说明lsb-release包未安装执行sudo apt update sudo apt install -y lsb-release。第二检查 Java 环境java -version # 正确输出示例 # openjdk version 17.0.8 2023-07-18 # OpenJDK Runtime Environment (build 17.0.87-Ubuntu-118.04) # OpenJDK 64-Bit Server VM (build 17.0.87-Ubuntu-118.04, mixed mode, sharing)如果显示command not found执行sudo apt update sudo apt install -y openjdk-17-jre-headless # 安装后必须执行以下命令确保 java 命令指向正确版本 sudo update-alternatives --config java # 在交互式菜单中选择 openjdk-17-jre-headless 对应的编号通常是 2第三开放防火墙端口如果启用 ufwsudo ufw status verbose # 如果状态是 Status: active则执行 sudo ufw allow 8080 sudo ufw reload提示Ubuntu 18.04 默认不启用 ufw但很多企业镜像会预装。ufw status是必查项漏掉它Jenkins 装好了你也连不上。3.2 下载、校验、部署 Jenkins WAR 包每一步都可验证下载官方 war 包cd /tmp wget https://get.jenkins.io/war-stable/2.426.3/jenkins.war # 注意URL 中的 war-stable 是关键它指向 LTS 版本war 则指向 weekly 版本校验文件完整性强烈建议# 下载 SHA256 校验码 wget https://get.jenkins.io/war-stable/2.426.3/jenkins.war.sha256 # 计算本地文件的 SHA256 sha256sum jenkins.war # 输出应与 jenkins.war.sha256 文件内容完全一致 # 如果不一致立即删除 jenkins.war重新下载这一步看似繁琐但能避免下载到被中间人篡改的恶意 war 包。我曾在一个客户现场因网络劫持导致下载的 war 包被植入挖矿脚本java -jar jenkins.war启动后CPU 占用率瞬间飙到 99%。创建专用用户与工作目录# 创建 jenkins 用户禁止 shell 登录主目录设为 /var/lib/jenkins sudo useradd -r -m -U -d /var/lib/jenkins -s /bin/false jenkins # 创建 jenkins 组并将当前用户加入方便后续管理 sudo groupadd jenkins sudo usermod -aG jenkins $USER # 设置目录权限 sudo chown -R jenkins:jenkins /var/lib/jenkins sudo chmod -R 755 /var/lib/jenkins注意-s /bin/false是安全关键。Jenkins 进程以 jenkins 用户身份运行该用户不能登录系统极大降低被提权的风险。/var/lib/jenkins是 Jenkins 的默认 HOME所有 job 配置、构建历史、插件都存在这里权限必须严格。启动 Jenkins前台测试sudo -u jenkins java -jar /tmp/jenkins.war \ --httpPort8080 \ --httpsPort-1 \ --prefix/jenkins \ --httpListenAddress0.0.0.0 \ --ajp13Port-1 \ --webroot/var/cache/jenkins/war \ --pluginManagerfalse \ --daemonfalse \ --logfile/var/log/jenkins/jenkins.log参数详解--httpPort8080监听 8080 端口这是标准。--httpsPort-1禁用 HTTPS简化初期配置生产环境必须启用。--prefix/jenkins所有 URL 加上/jenkins前缀避免与 Nginx/Apache 冲突。--httpListenAddress0.0.0.0监听所有网卡不只是 localhost。--webroot/var/cache/jenkins/war指定 war 解压目录避免每次启动都解压到临时目录。--pluginManagerfalse禁用插件管理器首次启动时不联网下载插件加速初始化。--daemonfalse前台运行便于观察日志。此时终端会滚动输出大量日志。等待出现Jenkins is fully up and running字样即表示启动成功。打开浏览器访问http://your-server-ip:8080/jenkins你应该看到 Jenkins 的初始设置页面。3.3 首次配置与管理员密码获取那个藏在日志里的“金钥匙”Jenkins 首次启动后会生成一个 32 位的管理员密码用于解锁控制台。它不在/var/lib/jenkins/secrets/initialAdminPassword文件里这是常见误区而是在启动日志中。正确获取方式# 如果你是前台启动直接看终端最后一屏 # 如果已关闭终端执行 sudo cat /var/log/jenkins/jenkins.log | grep Please use the following password # 或者更精准 sudo grep -A 5 Jenkins initial setup is required /var/log/jenkins/jenkins.log输出类似Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation: 5e3a8b1c2d4f6a8b9c0d1e2f3a4b5c6d复制5e3a8b1c2d4f6a8b9c0d1e2f3a4b5c6d这串字符在浏览器页面的输入框中粘贴。后续步骤选择 “Install suggested plugins”它会安装git,pipeline,workflow-aggregator,mailer等核心插件足够支撑 80% 的场景。创建第一个管理员账户用户名、密码、邮箱邮箱用于接收构建失败通知。实例配置将 Jenkins URL 设为http://your-server-ip:8080/jenkins/注意结尾斜杠这是后续所有 webhook、API 调用的基础。实操心得我建议在 “Customize Jenkins” 页面取消勾选 “Install suggested plugins”改为手动选择。因为 “suggested” 插件列表里包含cloudbees-folder、javadoc等非必需插件它们会拖慢首次启动速度。手动勾选git,pipeline,workflow-aggregator,mailer,credentials-binding这五个5 分钟内就能完成初始化。3.4 创建 systemd 服务文件让 Jenkins 真正“活”在系统里前台启动只是验证生产环境必须用 systemd 管理。创建/etc/systemd/system/jenkins.service[Unit] DescriptionJenkins Automation Server Documentationhttps://www.jenkins.io/ Wantsnetwork-online.target Afternetwork-online.target [Service] Typesimple Userjenkins Groupjenkins EnvironmentJAVA_HOME/usr/lib/jvm/java-17-openjdk-amd64 EnvironmentJENKINS_HOME/var/lib/jenkins EnvironmentJENKINS_OPTS--httpPort8080 --prefix/jenkins --webroot/var/cache/jenkins/war ExecStart/usr/bin/java -Djava.awt.headlesstrue -Djenkins.install.runSetupWizardfalse -jar /tmp/jenkins.war $JENKINS_OPTS Restarton-failure RestartSec10 LimitNOFILE65536 LimitNPROC65536 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target关键参数说明EnvironmentJAVA_HOME...显式指定 Java 17 路径避免java -version和实际运行时不一致。ExecStart...完整启动命令-Djenkins.install.runSetupWizardfalse禁用向导防止重启后二次初始化。LimitNOFILE65536提高文件描述符上限Jenkins 构建时会打开大量文件。StandardOutputjournal日志统一由 journalctl 管理sudo journalctl -u jenkins -f实时查看。启用并启动服务sudo systemctl daemon-reload sudo systemctl enable jenkins sudo systemctl start jenkins sudo systemctl status jenkinsstatus输出中Active:行必须是active (running)且Main PID:后面跟着一个数字如12345这才是真正的成功。如果显示failed执行sudo journalctl -u jenkins -n 100 --no-pager查看最后 100 行错误日志。4. 常见问题与排查技巧实录那些让我熬夜到凌晨三点的报错4.1 “Connection refused” 或 “This site can’t be reached”端口与网络的迷魂阵这是最高频的问题原因却五花八门现象可能原因排查命令解决方案curl http://localhost:8080/jenkins返回Failed to connectJenkins 进程未运行sudo systemctl status jenkinssudo systemctl start jenkinscurl http://localhost:8080/jenkins成功但外网 IP 访问失败防火墙拦截sudo ufw statussudo ufw allow 8080curl http://localhost:8080/jenkins成功但http://ip:8080/jenkins失败--httpListenAddress未设为0.0.0.0sudo systemctl cat jenkins | grep ListenAddress修改 service 文件添加--httpListenAddress0.0.0.0curl http://localhost:8080/jenkins返回 404--prefix与 URL 不匹配sudo systemctl cat jenkins | grep prefix确保浏览器 URL 与--prefix值完全一致大小写、斜杠独家技巧用sudo ss -tuln \| grep :8080查看 8080 端口是否被java进程监听。如果没输出说明 Jenkins 根本没起来如果输出是127.0.0.1:8080说明只监听了本地回环必须改--httpListenAddress。4.2 “Plugin installation failed”插件世界的信任危机在 “Manage Plugins” 页面安装插件时常遇到Failed to download from https://updates.jenkins.io/download/plugins/...。这不是网络问题而是证书信任问题。根本原因Ubuntu 18.04 的ca-certificates包版本较老20180409无法验证 Jenkins 更新中心updates.jenkins.io使用的 Lets Encrypt 新证书链。解决方案二选一升级 ca-certificates推荐sudo apt update sudo apt install -y ca-certificates # 升级后重启 Jenkins sudo systemctl restart jenkins临时禁用 SSL 验证仅测试环境 在 Jenkins 系统配置中找到 “Advanced” 选项卡将 “Update Site URL” 改为http://updates.jenkins.io/download注意是http不是https。生产环境严禁此操作注意failed to resolve host name mirrors.tuna.tsinghua.edu.cn这类报错是因为你手动修改了update-center.json把镜像源指向了清华源。Jenkins 2.300 已移除对自定义镜像源的支持强行修改会导致插件管理器彻底失效。请恢复默认设置。4.3 “No valid crumb was included in the request”CSRF 保护下的 API 调用失败当你用curl或 Python 脚本调用 Jenkins REST API如触发构建时常遇到 403 错误。这是因为 Jenkins 启用了 CSRF 保护要求每个 POST 请求必须携带一个动态生成的crumb。正确调用流程# 第一步获取 crumb CRUMB$(curl -s -u admin:password http://localhost:8080/jenkins/crumbIssuer/api/json | jq -r .crumb) # 第二步用 crumb 发起构建 curl -s -u admin:password -H Jenkins-Crumb: $CRUMB -X POST http://localhost:8080/jenkins/job/my-job/buildjq是解析 JSON 的利器sudo apt install -y jq即可安装。没有jq也可以用grep -o crumb:[^]*提取但可靠性低。4.4 “Permission denied” 写入 workspaceLinux 权限的无声绞杀当 Jenkins 执行 Shell 构建步骤如mvn clean package时报错Permission denied通常不是 Jenkins 用户没权限而是 workspace 目录的所有者是root而 Jenkins 进程以jenkins用户运行。根因你在Execute shell步骤里写了sudo mkdir /tmp/myapp导致/tmp/myapp所有者变成root。后续 Jenkins 无法在其中创建文件。解决方法永远不要在 Jenkins 构建步骤里用sudo。Jenkins 本身就有足够的权限管理自己的 workspace。如果必须用 root 权限如安装系统包在Execute shell中切换用户sudo -u root apt-get install -y some-package。定期清理 workspace在 Job 配置中勾选 “Delete workspace before build starts”。5. 进阶配置与生产就绪让 Jenkins 真正扛住业务流量5.1 配置反向代理Nginx隐藏端口、启用 HTTPS、提升安全性直接暴露:8080端口是危险的。用 Nginx 做反向代理既能绑定域名如ci.yourcompany.com又能启用 HTTPS还能做负载均衡。安装 Nginxsudo apt install -y nginx sudo systemctl enable nginx sudo systemctl start nginx创建 Nginx 配置/etc/nginx/sites-available/jenkinsupstream jenkins { server 127.0.0.1:8080; } server { listen 80; server_name ci.yourcompany.com; # 重定向 HTTP 到 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name ci.yourcompany.com; ssl_certificate /etc/letsencrypt/live/ci.yourcompany.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ci.yourcompany.com/privkey.pem; location /jenkins/ { proxy_pass http://jenkins/jenkins/; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键传递 WebSocket 头否则 Blue Ocean 界面会断连 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control public, immutable; } }启用配置sudo ln -sf /etc/nginx/sites-available/jenkins /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx提示SSL 证书用certbot一键申请sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d ci.yourcompany.com。它会自动修改 Nginx 配置并续期。5.2 JVM 参数调优告别 OutOfMemoryError默认的 JVM 参数-Xmx256m对小型项目够用但一旦并发构建数 3就会频繁 GC甚至 OOM。修改/etc/systemd/system/jenkins.service的ExecStart行ExecStart/usr/bin/java \ -Xms1g -Xmx4g \ -XX:UseG1GC \ -XX:MaxGCPauseMillis100 \ -Djava.awt.headlesstrue \ -Djenkins.install.runSetupWizardfalse \ -jar /tmp/jenkins.war $JENKINS_OPTS-Xms1g -Xmx4g堆内存初始 1G最大 4G。根据服务器内存按比例调整总内存 16G给 Jenkins 4G 是安全的。-XX:UseG1GC启用 G1 垃圾回收器更适合大堆内存。-XX:MaxGCPauseMillis100目标 GC 暂停时间 100ms减少构建卡顿。修改后执行sudo systemctl daemon-reload sudo systemctl restart jenkins。5.3 备份与恢复Jenkins 的生命线Jenkins 的所有数据都在/var/lib/jenkins。备份它就是备份你的整个 CI/CD 流水线。全自动备份脚本/usr/local/bin/backup-jenkins.sh#!/bin/bash DATE$(date %Y%m%d_%H%M%S) BACKUP_DIR/backup/jenkins JENKINS_HOME/var/lib/jenkins sudo mkdir -p $BACKUP_DIR sudo tar -czf $BACKUP_DIR/jenkins-backup-$DATE.tar.gz -C /var/lib jenkins # 只保留最近 7 天的备份 find $BACKUP_DIR -name jenkins-backup-*.tar.gz -mtime 7 -delete设置定时任务sudo chmod x /usr/local/bin/backup-jenkins.sh # 每天凌晨 2 点执行 echo 0 2 * * * root /usr/local/bin/backup-jenkins.sh | sudo tee /etc/cron.d/jenkins-backup恢复操作sudo systemctl stop jenkins sudo rm -rf /var/lib/jenkins sudo tar -xzf /backup/jenkins/jenkins-backup-20231001_020000.tar.gz -C /var/lib/ sudo chown -R jenkins:jenkins /var/lib/jenkins sudo systemctl start jenkins我的个人体会是Jenkins 的价值不在于它多酷炫而在于它多可靠。一个能随时回滚到昨天状态的备份策略比任何花哨的 Pipeline 语法都重要。我见过太多团队因为没做备份一次误删 job 配置导致整条发布流水线瘫痪 8 小时。备份不是可选项是上线前的强制动作。