当前位置: 首页 > news >正文

Ubuntu 20.04 原生安装 Jenkins 完整实践指南

1. 项目概述:为什么在 Ubuntu 20.04 上亲手安装 Jenkins 是件值得花两小时的事

Jenkins 不是点一下“下一步”就能跑起来的图形化工具,它是一套需要你真正理解 Linux 系统服务、Java 运行时、网络端口、用户权限和持续集成逻辑的基础设施。很多人搜“Jenkins Ubuntu 20.04 安装”,点开前五条结果,照着复制粘贴完发现:页面打不开、插件装不上、Jenkins 启动后立刻崩溃、或者连初始管理员密码都找不到——不是教程错了,而是 Ubuntu 20.04 这个发行版本身有它的脾气:它默认用 systemd 管理服务,OpenJDK 版本锁定在 11,防火墙 ufw 默认启用,/var/lib/jenkins 目录权限极敏感,而 Jenkins 官方 deb 包又恰好在 2020 年底起彻底弃用 Java 8 支持。你看到的“jenkins 安装与配置”“jenkins 自动部署”“jenkins 打包发布”这些热搜词,背后全是同一个前提:Jenkins 必须先稳稳当当地跑在你的 Ubuntu 20.04 机器上,且能被你完全掌控。这不是一个“装好就行”的任务,而是一次对 Linux 系统管理能力的现场压力测试。我带过十几期 DevOps 实训班,90% 的学员卡在第一步——不是不会敲命令,而是不知道每条命令背后在改什么、为什么必须这么改。比如sudo systemctl daemon-reload看似只是刷新配置,实则是在告诉 systemd:“你之前加载的 jenkins.service 文件已经过期了,现在这个新文件才是权威”。再比如chown -R jenkins:jenkins /var/lib/jenkins,表面是改属主,深层逻辑是让 Jenkins 进程以 jenkins 用户身份运行时,能真正读写自己的工作目录,否则后续所有构建任务都会因权限拒绝而失败。这篇文章不讲“Jenkins 是什么”,也不堆砌 Pipeline 语法,只聚焦一件事:用最贴近生产环境的方式,在 Ubuntu 20.04 上从零部署一个可长期维护、可排查故障、可扩展插件、可对接 Git 和 Maven 的 Jenkins 实例。适合正在搭建 CI/CD 流水线的开发工程师、运维新人、测试自动化负责人,以及任何想摆脱“一键脚本依赖症”、真正搞懂持续集成底层逻辑的技术实践者。

2. 整体设计思路与方案选型:为什么不用 Docker?为什么坚持 APT 官方源?

2.1 拒绝 Docker 安装的三个硬性理由

你可能已经看到大量“docker 安装高版本的 jenkins”“docker 部署 jenkins”这类热词,但我要明确告诉你:在 Ubuntu 20.04 上首次部署 Jenkins,Docker 不是捷径,而是隐藏陷阱的迷雾。原因有三:

第一,网络隔离导致 Git/SVN/SSH 认证链断裂。Jenkins 构建任务常需拉取私有 Git 仓库代码(如 GitHub Enterprise、GitLab 私有实例),这要求 Jenkins 能访问公司内网或跳板机。Docker 容器默认使用 bridge 网络,宿主机的 SSH agent forwarding、~/.ssh/config 别名、甚至 ~/.gitconfig 中的 http.proxy 配置,全都不自动透传进容器。你得手动挂载 socket、配置代理、处理密钥权限,最终配置复杂度远超原生安装。我实测过:一个原本 5 分钟配好的 Git 凭据,在 Docker 里折腾了 2 小时才解决 host key verification failed。

第二,插件离线安装与磁盘空间失控。企业内网环境严禁外网直连,所有 Jenkins 插件必须离线安装(如jenkins 离线安装插件是高频搜索)。Docker 镜像体积动辄 800MB+,每次更新插件都要 rebuild 镜像、push 到私有 registry、再 pull 下来,而/var/lib/jenkins/plugins/目录在容器内若未用 volume 挂载,重启即丢失。更糟的是,Docker 的 overlay2 存储驱动在 Ubuntu 20.04 上对小文件频繁读写性能较差,Jenkins 日志轮转、workspace 清理极易触发 I/O wait 升高,构建耗时莫名增加 30%。

第三,系统级调试能力被阉割。当 Jenkins 控制台报错 “Failed to resolve host name mirrors.tuna.tsinghua.edu.cn”(这是清华镜像源 DNS 解析失败的典型错误),你需要查的是宿主机的/etc/resolv.conf、systemd-resolved 状态、甚至 NetworkManager 配置。但在容器里,你得先进入容器docker exec -it jenkins bash,再查容器内部网络,而容器网络和宿主机根本不是一回事。真正的故障往往藏在宿主机层面:比如 ufw 防火墙规则误删了 8080 端口放行,或 AppArmor 策略限制了 Java 进程访问/proc/sys/vm/swappiness——这些,Docker 层面根本看不到。

2.2 坚持 APT 官方源而非手动下载 WAR 包

另一个常见误区是直接下载jenkins.war手动运行:java -jar jenkins.war --httpPort=8080。这看似灵活,实则埋下三颗雷:

  • 无 systemd 集成,无法开机自启。Ubuntu 20.04 的服务生命周期由 systemd 全权管理。手动运行的 Java 进程不属于任何 unit,systemctl start jenkins会失败,journalctl -u jenkins查不到日志,sudo reboot后 Jenkins 彻底消失。而 APT 安装的包自带/lib/systemd/system/jenkins.service,开箱即用。

  • Java 版本兼容性黑洞。Jenkins 2.346+ 强制要求 OpenJDK 11 或更高,但 Ubuntu 20.04 默认java -version返回的是 OpenJDK 11.0.11,而某些手动下载的 WAR 包(尤其旧版)仍尝试调用javax.xml.bind(JDK 9+ 已移除),导致启动报NoClassDefFoundError。APT 源的包经过 Canonical 官方严格测试,确保与系统 JDK 11 完全兼容。

  • 升级路径断裂apt update && apt upgrade可一键升级 Jenkins 及其依赖(如jenkins-clijenkins-common),而 WAR 包升级需手动下载、校验 SHA256、替换文件、重启进程,稍有不慎就覆盖掉自定义的init.groovy.d/初始化脚本。

2.3 为什么选择清华 TUNA 镜像源而非官方源

Ubuntu 20.04 默认的archive.ubuntu.com源在国内访问极慢,而 Jenkins 官方 apt 源https://pkg.jenkins.io/debian-stable也常因网络波动超时(你搜到的 “jenkins failed to resolve host name mirrors.tuna.tsinghua.edu.cn” 错误,恰恰说明很多人已转向清华源,只是没配对)。清华 TUNA 镜像源同步频率高(每小时一次)、CDN 节点多、HTTPS 证书有效,且路径与官方源完全一致,只需替换 URL 即可无缝切换。关键在于:TUNA 源的Release.gpg签名密钥与 Jenkins 官方密钥一致apt校验机制不会报错。我对比过 10 次安装耗时:官方源平均 7 分钟(含超时重试),TUNA 源稳定在 42 秒内。这不是“图快”,而是把不可控的网络变量,变成可控的本地操作。

3. 核心细节解析与实操要点:从系统准备到首屏登录的 7 个生死关

3.1 系统级前置检查:3 条命令定生死

在敲任何apt install之前,必须执行这三步检查。跳过任一环节,后续 90% 的问题都源于此。

第一步:确认 Java 版本与架构

java -version

正确输出必须包含openjdk version "11.0.11"且末尾是Ubuntu-0ubuntu2.20.04(表示是 Ubuntu 官方打包的 OpenJDK 11)。如果显示1.8.0_30217.0.1,说明你手动装过其他 JDK,必须卸载:

sudo apt remove openjdk-8-jdk openjdk-17-jdk sudo apt autoremove

提示:Ubuntu 20.04 的openjdk-11-jdk是唯一受 Jenkins 官方支持的 LTS 版本。JDK 17 虽然技术上可行,但 Jenkins 插件生态(如 Subversion、Maven Integration)在 2022 年前未全面适配,会导致ClassNotFoundException

第二步:验证 systemd 服务管理状态

sudo systemctl is-active jenkins

首次安装前应返回unknown(服务不存在)。如果返回activefailed,说明之前装过 Jenkins 但未清理干净,必须执行彻底卸载:

sudo apt purge jenkins sudo rm -rf /var/lib/jenkins /var/cache/jenkins /var/log/jenkins sudo systemctl daemon-reload

注意:apt purgeapt remove更彻底,它会删除所有配置文件。很多“jenkins 启动失败”问题,根源就是残留的/var/lib/jenkins/config.xml里有损坏的 XML 标签。

第三步:检查 8080 端口占用

sudo ss -tuln | grep ':8080'

如果输出非空(如LISTEN 0 128 *:8080 *:* users:(("java",pid=1234,fd=10))),说明已有进程占用了 Jenkins 默认端口。此时不能强行 kill,而应修改 Jenkins 配置:

sudo nano /etc/default/jenkins

找到HTTP_PORT=8080行,改为HTTP_PORT=8081,保存退出。这是生产环境最佳实践——避免与 Tomcat、Nginx 等其他服务冲突。

3.2 APT 源配置:手把手配清华 TUNA 镜像(含密钥验证)

Ubuntu 20.04 的 apt 源配置分散在/etc/apt/sources.list/etc/apt/sources.list.d/下。为避免污染系统源,我们新建独立文件:

sudo nano /etc/apt/sources.list.d/jenkins.list

输入以下内容(注意:focal是 Ubuntu 20.04 的代号,不可写成bionicjammy):

deb https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable binary/

保存后,必须导入 Jenkins 官方 GPG 密钥,否则apt update会报NO_PUBKEY错误:

curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \ /usr/share/keyrings/jenkins-keyring.asc > /dev/null

关键细节:这里用的是jenkins.io-2023.key(2023 年更新的密钥),而非旧文档中的jenkins-ci.org.key。后者已于 2022 年 12 月停用,用错密钥会导致apt update失败。清华 TUNA 镜像源同步的是官方密钥,所以此步骤必须做,且必须用tee写入/usr/share/keyrings/(Ubuntu 20.04 的新密钥存储路径)。

验证密钥是否生效:

apt-key list | grep -A1 "Jenkins"

应看到pub rsa4096 2023-01-19 [SC] [expires: 2025-01-18]字样。

3.3 安装过程中的 3 个隐藏陷阱与绕过方案

执行sudo apt update && sudo apt install jenkins后,安装过程看似顺利,但实际暗藏三处易崩溃点:

陷阱一:/var/lib/jenkins目录权限初始化失败
Jenkins 安装脚本会在 postinst 阶段执行chown -R jenkins:jenkins /var/lib/jenkins,但如果/var/lib/jenkins已存在且属主是 root,chown会静默失败(无报错),导致后续 Jenkins 启动时因无权写入logs/目录而崩溃。解决方案:安装前手动创建并赋权:

sudo mkdir -p /var/lib/jenkins sudo chown -R jenkins:jenkins /var/lib/jenkins sudo chmod 755 /var/lib/jenkins

陷阱二:systemd 服务文件被覆盖
Ubuntu 20.04 的jenkins包自带/lib/systemd/system/jenkins.service,但如果你之前手动创建过同名文件,apt install可能提示jenkins.service: local file exists, keeping old one,导致服务无法启动。强制覆盖:

sudo dpkg-reconfigure jenkins

选择Yes覆盖配置文件。

陷阱三:ufw 防火墙拦截 8080 端口
即使 Jenkins 进程启动成功,外部也无法访问。检查:

sudo ufw status verbose

如果输出中8080端口状态为DENY,立即放行:

sudo ufw allow 8080 sudo ufw reload

实操心得:我见过最诡异的案例——Jenkins 控制台能打开,但所有插件安装按钮点击无反应。最后发现是 ufw 的outbound规则阻止了 Jenkins 向updates.jenkins.io发起 HTTPS 请求。解决方案是放行出站:sudo ufw default allow outgoing

3.4 首次启动与初始密码获取:为什么cat /var/lib/jenkins/secrets/initialAdminPassword常失效

安装完成后,执行:

sudo systemctl start jenkins sudo systemctl status jenkins

理想状态是active (running)。如果卡在activating (start),立即查日志:

sudo journalctl -u jenkins -f

常见错误:

  • java.lang.OutOfMemoryError: Metaspace→ JVM 元空间不足,需修改/etc/default/jenkins中的JAVA_OPTS
    JAVA_OPTS="-Djava.awt.headless=true -XX:+UseG1GC -XX:MaxMetaspaceSize=512m"
  • Permission denied: /var/lib/jenkins/jobs→ 说明chown步骤失败,重新执行sudo chown -R jenkins:jenkins /var/lib/jenkins

获取初始密码时,90% 的人直接cat /var/lib/jenkins/secrets/initialAdminPassword,但常返回空或乱码。这是因为 Jenkins 在首次启动时会生成该文件,但若启动失败,文件不会创建。正确流程是:

  1. 确保sudo systemctl status jenkins显示active
  2. 等待 60 秒(Jenkins 首次启动需初始化插件索引);
  3. 执行:
    sudo cat /var/lib/jenkins/secrets/initialAdminPassword 2>/dev/null || echo "密码文件未生成,请检查 jenkins.service 状态"

4. 实操过程与核心环节实现:从解锁控制台到配置第一个 Maven 任务

4.1 控制台解锁后的 5 项必做配置(避坑清单)

浏览器访问http://your-server-ip:8080,输入初始密码后,Jenkins 会引导安装推荐插件。切勿直接点“Install suggested plugins”——这是新手最大误区。推荐插件包含SubversionLDAP等你暂时用不到的组件,安装过程长达 15 分钟,且其中Docker Commons插件会因网络问题卡死,导致整个安装流程中断。正确做法是:

  1. 点 “Select plugins to install”→ 只勾选以下 4 个核心插件:

    • Git plugin(对接 GitHub/GitLab)
    • Pipeline(编写 Jenkinsfile 的基础)
    • Maven Integration plugin(编译 Java 项目)
    • Blue Ocean(现代化 UI,比经典界面直观 3 倍)
  2. 创建首个管理员用户:用户名设为admin,密码务必记录(后续所有凭证管理基于此用户)。

  3. 实例配置页,修改Jenkins URL
    默认是http://localhost:8080/,必须改成你的服务器真实 IP 或域名(如http://192.168.1.100:8080/)。否则 Git webhook 回调会失败,因为 Jenkins 会向localhost发送请求,而非你的公网地址。

  4. 关闭“允许匿名读取”
    进入Manage JenkinsConfigure Global Security→ 取消勾选Enable security下的Allow anonymous read access。否则任何人扫到你的 IP 都能查看构建历史。

  5. 设置时区
    Manage JenkinsConfigure SystemDefault Time ZoneAsia/Shanghai。否则构建日志时间戳全是 UTC,排查问题时要手动换算。

4.2 配置 Java 与 Maven 环境:为什么 Jenkins 不认你系统里的 Maven

Jenkins 的构建环境是隔离的,它不继承宿主机的PATHJAVA_HOME。即使你在终端执行mvn -v正常,Jenkins 任务仍会报mvn: command not found。解决方案是:

步骤一:在 Jenkins 中声明 JDK 11
Global Tool ConfigurationJDKAdd JDK

  • Name:jdk11
  • JAVA_HOME:/usr/lib/jvm/java-11-openjdk-amd64(Ubuntu 20.04 默认路径,用readlink -f $(which java)确认)

步骤二:声明 Maven 3.8.6+
Global Tool ConfigurationMavenAdd Maven

  • Name:maven3
  • MAVEN_HOME:/opt/maven(需先手动安装 Maven)

手动安装 Maven(Jenkins 不提供 Maven APT 包):

cd /tmp && wget https://downloads.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz sudo tar -xzf apache-maven-3.8.6-bin.tar.gz -C /opt/ sudo ln -s /opt/apache-maven-3.8.6 /opt/maven

注意:Maven 3.9.0+ 对 Java 11 兼容性有 Bug,必须用 3.8.6。这是jenkins 用 maven 编译找不到系统文件错误的根源——新版 Maven 的maven-wrapper会错误解析JAVA_HOME

步骤三:在任务中绑定工具
新建Maven project任务 →ConfigureGeneral→ 勾选Restrict where this project can be run→ 输入master(Jenkins 默认节点名);
BuildGoals and options输入clean package
Build Environment→ 勾选Provide Node & npm bin/ folder to PATH(虽是 Node 选项,但勾选后会修复 PATH 继承问题);
BuildJDKjdk11Maven Versionmaven3

4.3 创建第一个 Java 构建任务:从 Git 拉取到生成 JAR 包

以 Spring Boot 项目为例(假设 Git 仓库地址为https://github.com/yourname/demo-springboot.git):

  1. New Item→ 输入任务名demo-springboot-build→ 选择Maven projectOK

  2. Source Code ManagementGitRepository URLhttps://github.com/yourname/demo-springboot.git

  3. CredentialsAddJenkinsKind: Username with password

    • Username: 你的 GitHub 账号(非邮箱)
    • Password: GitHub Personal Access Token(不是账号密码!

    提示:GitHub 已禁用账号密码登录 Git,必须用 Token。生成路径:GitHub Settings →Developer settingsPersonal access tokensGenerate new token→ 勾选repo权限。

  4. Build Triggers→ 勾选Poll SCMScheduleH/5 * * * *(每 5 分钟检查一次 Git 提交);

  5. BuildGoals and optionsclean package -DskipTests(跳过测试加速构建);

  6. Post-build ActionsArchive the artifactsFiles to archivetarget/*.jar

保存后,点Build now。首次构建会下载 Maven 依赖(约 300MB),耗时较长。成功后,在Workspace中可看到target/demo-springboot-0.0.1-SNAPSHOT.jar

4.4 配置两个服务器凭证:实现从 Jenkins 到目标服务器的免密部署

jenkins 配置两个服务器凭证是高频需求,典型场景是:Jenkins 服务器(A)构建完 JAR,需自动拷贝到应用服务器(B)并重启服务。

凭证 1:Jenkins 服务器自身的 SSH 凭据(用于执行本地脚本)
Manage JenkinsManage CredentialsSystemGlobal credentialsAdd Credentials

  • Kind:SSH Username with private key
  • Scope:Global
  • ID:jenkins-ssh-local
  • Username:jenkins(Jenkins 进程运行用户)
  • Private Key:Enter directly→ 粘贴sudo cat /var/lib/jenkins/.ssh/id_rsa(若无,先生成:sudo -u jenkins ssh-keygen -t rsa -b 4096 -f /var/lib/jenkins/.ssh/id_rsa

凭证 2:目标应用服务器 B 的 SSH 凭据
同上,新增凭证:

  • ID:app-server-b
  • Username:deploy(目标服务器上的部署用户)
  • Private Key: 粘贴deploy用户的私钥(确保deploy用户有sudo systemctl restart myapp权限)

在构建后执行部署脚本
Post-build ActionsExecute shell script on remote host(需先安装Publish Over SSH插件)→

  • SSH Serverapp-server-b
  • Transfer SetFrom:target/demo-springboot-0.0.1-SNAPSHOT.jar
  • Remote directory:/opt/myapp/
  • Exec in pty勾选 →Commands:
    cd /opt/myapp sudo systemctl stop myapp sudo cp demo-springboot-0.0.1-SNAPSHOT.jar myapp.jar sudo systemctl start myapp

5. 常见问题与排查技巧实录:那些让你抓狂 3 小时的真问题

5.1 DNS 解析失败:Failed to resolve host name mirrors.tuna.tsinghua.edu.cn

这个错误不是 Jenkins 的锅,而是 Ubuntu 20.04 的systemd-resolved服务与网络管理器冲突所致。现象:apt update报错,但ping mirrors.tuna.tsinghua.edu.cn正常。

根因分析:Ubuntu 20.04 默认启用systemd-resolved,它监听127.0.0.53:53,但/etc/resolv.conf被 symlink 到/run/systemd/resolve/stub-resolv.conf,而该文件中 nameserver 是127.0.0.53,但systemd-resolved本身未正确配置上游 DNS。

三步解决法

  1. 查看当前 DNS 配置:

    systemd-resolve --status | grep "DNS Servers"

    如果输出为空或只有127.0.0.53,说明上游 DNS 未设置。

  2. 编辑 NetworkManager 配置:

    sudo nano /etc/NetworkManager/conf.d/10-dns.conf

    添加:

    [main] dns=systemd-resolved [global-dns] servers=114.114.114.114,223.5.5.5
  3. 重启服务:

    sudo systemctl restart systemd-resolved sudo systemctl restart NetworkManager

    验证:nslookup mirrors.tuna.tsinghua.edu.cn应返回正常 IP。

5.2 Jenkins 控制台空白或 JS 报错:Uncaught ReferenceError: Jenkins is not defined

这是典型的反向代理配置错误。当你用 Nginx 做反向代理(如jenkins 部署常见场景),却忘了配置X-Forwarded-*头。

Nginx 配置修正模板

location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; 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; # 关键!Jenkins 依赖此头生成正确 URL proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; }

然后在 JenkinsConfigure SystemJenkins URLhttps://your-domain.com/(注意是 HTTPS,不是 http://127.0.0.1:8080)。

5.3 构建任务卡在Cloning the remote Git repository:SSH 连接超时

git jenkins集成失败的主因是 Jenkins 进程无法读取 SSH 密钥。

排查路径

  1. 确认 Jenkins 运行用户是jenkinsps aux | grep jenkins
  2. 切换到该用户:sudo -u jenkins -s
  3. 测试 SSH 连接:ssh -T git@github.com
    • 若报Permission denied (publickey),说明密钥未加载;
    • 执行eval $(ssh-agent -s)ssh-add /var/lib/jenkins/.ssh/id_rsa
  4. ssh-agent启动命令写入 Jenkins 启动脚本:
    echo 'eval $(ssh-agent -s)' | sudo tee -a /var/lib/jenkins/.bashrc echo 'ssh-add /var/lib/jenkins/.ssh/id_rsa' | sudo tee -a /var/lib/jenkins/.bashrc

5.4 插件安装失败:Plugin installation failed: No such file or directory

这是 Jenkins 2.346+ 的安全策略变更。默认禁止从远程 URL 安装插件,必须手动上传.hpi文件。

离线安装完整流程

  1. 在联网机器上访问https://updates.jenkins.io/download/plugins/,下载所需插件(如git.hpi);
  2. 上传到 Jenkins 服务器:scp git.hpi user@server:/tmp/
  3. 进入 Jenkins 控制台 →Manage JenkinsManage PluginsAdvancedUpload Plugin→ 选择/tmp/git.hpi
  4. 重启 Jenkins:sudo systemctl restart jenkins

实操心得:我曾为解决jenkins 如何通过跳板机登录指定服务器,折腾了整整一个下午。最终发现,不是 Jenkins 配置问题,而是跳板机的sshd_configAllowTcpForwarding no被设为no。修改后加sudo systemctl restart ssh,问题瞬间解决。这提醒我:Jenkins 的问题,70% 在它之外的系统层。

6. 后续可扩展方向:从单机 Jenkins 到生产级 CI/CD

完成上述步骤,你已拥有一个健壮的 Jenkins 实例。但这只是起点。根据你搜索的热词jenkins cicd 介绍jenkins持续集成测试jenkins自动化部署,下一步自然延伸:

  • 接入 GitLab Webhook:替代轮询 SCM,实现push后秒级触发构建。关键点:GitLab 项目SettingsWebhooks→ URL 填http://your-jenkins-ip:8080/project/your-job-name,Token 与 Jenkins 中GitLab插件配置一致。
  • Pipeline as Code:将构建逻辑写入Jenkinsfile,存于 Git 仓库根目录。例如:
    pipeline { agent any stages { stage('Checkout') { steps { checkout scm } } stage('Build') { steps { sh 'mvn clean package -DskipTests' } } stage('Deploy') { steps { sh 'scp target/*.jar user@server:/opt/app/' } } } }
  • Docker 镜像构建:结合jenkins pipline java项目 push 到harbor镜像,在 Pipeline 中加入sh 'docker build -t harbor.example.com/myapp:${BUILD_NUMBER} .'sh 'docker push harbor.example.com/myapp:${BUILD_NUMBER}'

这些都不是空中楼阁。我去年帮一家 IoT 公司落地时,就是从这篇文档的 Ubuntu 20.04 原生安装起步,三个月后实现了 200+ 设备固件的全自动编译、签名、OTA 推送。Jenkins 本身不难,难的是你愿不愿意沉下心,一行命令一行命令地理解它与 Linux 系统的每一次交互。当你能看着journalctl -u jenkins的日志,准确判断出是内存不足还是磁盘满,你就真正跨过了那道门槛。

http://www.jsqmd.com/news/1068554/

相关文章:

  • Ubuntu 20.04部署MySQL 8.0:systemd管理、认证插件与安全配置全解析
  • llama.cpp本地大模型部署指南:从原理到实战优化
  • Lightdash:基于dbt的BI-as-Code平台,用AI与代码重构数据分析工作流
  • TRAE SOLO模式:终端原生的轻量级AI编码协作范式
  • Python列表添加操作本质:append、extend、insert的结构控制逻辑
  • Spring AOP实现数据库字段透明加解密:MyBatis/JPA敏感数据安全存储方案
  • MC68341串行与定时器模块编程实战:从寄存器配置到驱动开发
  • CentOS 7 源码编译 ngx_pagespeed 实战指南
  • 大模型研发为何没有‘灵魂缔造者’?解析GPT-4o背后的系统工程本质
  • Katoolin:在Ubuntu/Debian上一键安装Kali Linux渗透测试工具
  • 从RSA大会Semgrep Multimodal到PyTorch Lightning供应链攻击:AI时代代码安全新挑战
  • Windows本地AI交互新范式:ChatGPT 5.3桌面版深度解析
  • 嵌入式系统启动全解析:Flash编程与监控程序初始化实战
  • DeepResearch:基于LangGraph的可审计科研智能体工作流
  • React Keys不是语法糖:它是Fiber协调与状态稳定的底层契约
  • GPT-5.5不存在?解析OpenAI模型命名规范与API错误根源
  • Ansible在Ubuntu 14.04上部署PHP应用的实战指南
  • Ollama+GLM-4.7+Claude Code本地开发闭环真相
  • AES-GCM与AES-SIV加密模式实战:原理、选型与Python代码实现
  • Ansible 声明式配置管理:从 YAML 语法到生产级状态收敛
  • Go指针原理与nil安全实践:从内存模型到GC优化
  • OpenClaw:面向知识工作者的可进化AI工作流引擎
  • Ubuntu 18.04 + GitLab 13.12.15 稳定部署实战指南
  • Python自动化新选择:Playwright从入门到工程化实践指南
  • Airtable + Gatsby 构建时数据集成与 GraphQL 安全实践
  • Bottle+CentOS 7生产部署:轻量Web服务的可控落地实践
  • vLLM推理降本核心:GPU基础设施与运行时契约深度解析
  • MC9S08SF4 FDS模块实战:硬件级故障保护与嵌入式系统安全设计
  • DigitalOcean账户安全实战:TOTP、API密钥与SSH密钥全生命周期管控
  • 技术团队规模化不是堆人堆机器:识别临界失稳点的五大数据信号