CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Linux 服务器入门/课时/包管理
RawBlame
课时目录12 节

Linux 服务器入门

  1. 01Linux 是什么
  2. 02Shell 与 Bash
  3. 03文件系统与权限
  4. 04常用命令
  5. 05编辑器与配置
  6. 06进程与服务
  7. 07用户与 sudo
  8. 08包管理
  9. 09SSH 与密钥
  10. 10防火墙与端口
  11. 11部署 CodeRoadMap
  12. 12综合练习

包管理

apt/yum、安装 Node/Java/MySQL。

30 分钟

包管理

这一课你将能做到

  1. 用 apt 完成完整生命周期:更新索引 → 安装 → 查看信息/文件清单 → 升级 → 卸载清理,并说清 update 与 upgrade 的区别
  2. 在 Ubuntu 上装好 CodeRoadMap 的运行时三件套:OpenJDK 17、Nginx、Node 20(NodeSource 源),并用版本命令验证
  3. 会认 RedHat 系的 dnf/yum 对应命令,理解「软件源」概念,知道装的东西被放到了哪里(dpkg -L)

为什么要学

部署 Java 服务第一步永远是「装环境」:JDK、Nginx、MySQL、Node。装对了吗?为什么 apt install openjdk-17-jdk 报找不到?为什么别人机器上 node -v 是 20 你的还是 12?这些问题的答案全在包管理里。

包管理器解决三个问题:从哪下(软件源/仓库)、装到哪(文件清单与路径)、谁管着(依赖与版本)。理解了这三个问题,你就从「复制安装命令」升级到「知道每条安装命令在干什么」。

先建立图像

包管理的两层结构

apt(高级,推荐日常用)        dnf/yum(RHEL 系对应物)
  │  自动解决依赖、整包管理
  ▼
dpkg(底层)                  rpm(RHEL 系对应物)
  │  真正解压 .deb 落盘、登记文件清单
  ▼
系统文件(/usr/bin/java 等)

软件源:apt 的「地址簿」

/etc/apt/sources.list 与 /etc/apt/sources.list.d/*.sources   ← Ubuntu 24.04 新格式
        │
        ▼
apt update:只刷新「地址簿」——拉取各源的最新软件清单到本地缓存
apt upgrade:按缓存里的清单,真的去下载并升级已装的软件

这就是面试题「update 和 upgrade 区别」的图像:update 刷目录,upgrade 动真格。不 update 就 upgrade = 拿着旧目录找货,轻则装到旧版本,重则 404。

跟着做

步骤 1:apt 生命周期八连(先在干净机器走一遍)

sudo apt update                     # ① 刷新软件源索引(每次装软件前先跑)
apt list --upgradable               # ② 看有哪些可升级(只看不升)
apt search nginx                    # ③ 搜索:包名/描述含 nginx 的包
apt show nginx                      # ④ 看某包详情:版本、依赖、大小、维护者
sudo apt install nginx              # ⑤ 安装(自动带上依赖)
dpkg -L nginx | head -15            # ⑥ 这个包装了哪些文件、都在哪
apt list --installed | grep nginx   # ⑦ 确认已安装与版本
sudo apt remove nginx && sudo apt autoremove   # ⑧ 卸载 + 清理不再需要的依赖

补充两个清理相关:apt purge 包名(卸载且删配置文件)、apt clean(清掉 /var/cache/apt 的下载缓存,磁盘紧张时用)。

步骤 2:装 OpenJDK 17(后端主粮)

sudo apt update
sudo apt install -y openjdk-17-jdk-headless    # headless=无GUI组件,服务器首选
java -version                                  # openjdk version "17.0.x"
javac -version                                 # 编译器也有(JDK 而非 JRE)

# 装到哪了?管理方式是「替代方案」机制:
which java                                     # /usr/bin/java(这是个软链)
ls -l /usr/bin/java                            # → /etc/alternatives/java → 真身
ls /usr/lib/jvm/                               # 多个 JDK 共存的目录

# 多版本共存与切换(装了 21 之后再执行才有多个候选):
sudo apt install -y openjdk-21-jdk-headless    # (可选)再装一个 21
sudo update-alternatives --config java         # 交互选默认版本

生产建议:服务器只装需要的那个版本,别把 8/11/17/21 全装上,alternatives 指来指去容易把 systemd 服务的 java 路径搞乱。

步骤 3:装 Node 20(前端运行时,官方源版太旧)

Ubuntu 自带源的 node 是旧版本(20.04 上是 12),Next.js 14+ 要求 18+。正确姿势是加 NodeSource 源:

# ① 装 curl(若没有)并添加 NodeSource 20.x 源
sudo apt update && sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -

# ② 此时再装,走的就是新源
sudo apt install -y nodejs
node -v          # v20.x
npm -v

# ③ 验证源已登记
ls /etc/apt/sources.list.d/     # 多出 nodesource.list(24.04 是 .sources)

看懂那条 | sudo -E bash -:下载脚本 → 管道交给 bash 执行(-E 保留环境,- 表示读 stdin),它做的事就是往 sources.list.d 写 NodeSource 的源配置并导入签名钥匙。先理解再执行管道脚本,不明来源的 curl | bash 不要跑。

步骤 4:装 MySQL 8(验证服务型软件装完自启)

sudo apt update
sudo apt install -y mysql-server
systemctl status mysql --no-pager        # 装完即自动启动并 enable(服务型软件的特性)

sudo mysql -e "SELECT VERSION();"        # 本机 root 免密(auth_socket)验证版本

体会两点:① apt 装完「服务型软件」会自动注册 systemd 并启动——包管理课与进程课在这里接上了;② 版本命令(java/node/npm/mysql)是每次安装后的第一验收动作。

步骤 5:版本控制——装指定版本、锁定版本

apt list -a nginx                        # 源里有哪些候选版本
apt show nginx | grep Version

# 装指定版本(版本号先从 apt list -a 查,完整复制):
sudo apt install nginx=1.24.0-2ubuntu7   # 示例:以你查到的为准

# 锁定版本:apt upgrade 不再动它(生产「冻结」常用)
sudo apt-mark hold nginx
apt-mark showhold                        # 查看所有锁定
sudo apt-mark unhold nginx               # 解锁

步骤 6:RedHat 系对照速查(会认,能切换)

# 在 Rocky/Alma/CentOS 上的等价操作:
sudo dnf makecache                      # ≈ apt update(刷新元数据)
sudo dnf install java-17-openjdk-devel  # ≈ apt install openjdk-17-jdk
dnf search nginx                        # ≈ apt search
dnf info nginx                          # ≈ apt show
rpm -ql nginx | head                    # ≈ dpkg -L(列文件清单)
sudo dnf remove nginx                   # ≈ apt remove
sudo dnf autoremove                     # ≈ apt autoremove
动作Ubuntu/DebianRHEL 系
刷新索引apt updatednf makecache(多数命令自动做)
安装apt install xdnf install x
文件清单dpkg -L xrpm -ql x
查已装版本dpkg -l | grep xrpm -qa | grep x
加第三方源sources.list.d + curl 脚本dnf config-manager / .repo 文件

老 CentOS 7 的 yum 命令在 Rocky 9 上基本可无缝替换为 dnf(语法几乎一致)。

步骤 7: deb 包直装与故障排查

# 场景:公司内网给了你一个 .deb(如自研组件、旧版 JDK)
sudo dpkg -i 包名.deb            # 直装;若缺依赖会失败
sudo apt install -f             # -f fix:让 apt 自动补齐缺失依赖,然后再 dpkg -i 或它会接着装完

# 排查「包状态异常」:
dpkg -l | grep -E "^i[^i]|^..F"   # 非 ii 状态的都是问题包
sudo dpkg --configure -a          # 中断的安装卡住时,恢复配置流程

讲清楚要点

  1. apt 管的是「仓库里的软件」,你的 JAR 不归它管:backend.jar 是部署产物(tar/scp/rsync 搬运,进程课托管),nginx/mysql/jdk 才走 apt。别试图把业务包塞进 apt 体系。
  2. update 与 upgrade 永远先 update:装/升任何软件前先刷新索引,这是肌肉记忆。apt upgrade 升级所有软件(内核也会动),只升某包用 apt install 包名(会顺带升它)。
  3. 安装即登记:每个包的文件清单 dpkg 都记着(dpkg -L),卸载按清单回收——所以装包比手解 tar 干净;反过来,手解 tar 的东西(如自装 JDK 到 /opt)apt 不知道,卸载要自己删。两种方式别混用于同一软件。
  4. 第三方源是双刃剑:NodeSource/MySQL 官方源/Docker 源能带来新版本,但每个源都是供应链信任的延伸。原则:只加官方/可信源,看清 curl | bash 干了什么,出问题时知道去 /etc/apt/sources.list.d/ 删源。
  5. 服务型包装完即自启:mysql/nginx 安装后自动 systemctl enable + start。所以「装完要 systemctl status 看一眼」是标准验收;改配置后是 reload 而不是重装。
  6. 版本锁定用于「冻结」:apt-mark hold 适合「这个版本验证过,别让 upgrade 动它」。但锁太多包会让安全更新漏掉——锁定是例外,跟随更新是常态。

你可能会懵的地方

  • apt、apt-get、dpkg 什么关系? dpkg 是底层(装单个 .deb、不管依赖);apt-get 是老牌高层工具(稳定,脚本友好);apt 是 16.04 起面向人的新前端(进度条、apt list/apt search 等好用子命令),日常用 apt 即可。脚本里有人坚持 apt-get(输出格式更稳定),效果等价。
  • 为什么 apt install 报 Unable to locate package? 三种可能按顺序排:① 没先 apt update(索引空);② 源里确实没有(如 openjdk-17 在 20.04 的默认源没有?其实有;node 新版就肯定没有)→ 加对应官方源;③ 包名拼错 → apt search 关键词 找正确包名。
  • 装了 17 又装 21,Spring Boot 用的是哪个? 默认走 update-alternatives 指向的 java。明确指定:systemd 单元 ExecStart 写死绝对路径(/usr/lib/jvm/java-17-openjdk-amd64/bin/java)最稳——进程课的单元文件建议这么做。
  • apt upgrade 会不会把服务搞挂? 正常发行版仓库的更新经过测试,且服务升级通常有自动迁移。生产最佳实践:低峰期升级、升级前快照(云控制台)、升级后检查核心服务 systemctl status + 健康接口。apt-mark hold 冻结个别关键包也是手段。
  • Ubuntu 24.04 里 sources.list 变成 .sources 文件了? 是新格式(DEB822),信息相同只是排版结构化。/etc/apt/sources.list.d/ubuntu.sources。操作方式不变:apt update/install 照旧,加第三方源时注意看教程对应的是哪种格式。

错法对照

错法问题正解
不 apt update 直接 install找不到包或装到旧版装前必 update
apt upgrade -y 在生产乱跑升级中断/内核变更不可控生产升级前快照;重要包 hold
手动下载 tar.gz 解压 JDK,又想用 apt 管理它apt 不认,升级/卸载两不管二选一:apt 装或 /opt 手装并写死路径
`curl -fsSL xxxbash` 不看内容就跑供应链风险
dpkg -i 缺依赖后反复 dpkg越装越乱apt install -f 自动补依赖
把 backend.jar 放进 apt/dnf 体系业务包不是系统软件部署产物走 scp/rsync + systemd

卡点急救

  1. apt update 报 404 / Hash Sum mismatch:多为镜像缓存或源配置损坏。sudo apt clean && sudo rm -rf /var/lib/apt/lists/* && sudo apt update 重建索引;国内机器换镜像源(如阿里云镜像站,改 /etc/apt/sources.list)后同样操作。
  2. 安装中断后 apt 全程报锁(Could not get lock):确认没有其他 apt 进程在跑(ps aux | grep -E "apt|dpkg"),等待或结束后:sudo dpkg --configure -a 恢复;不要直接删 /var/lib/dpkg/lock(除非已确认无进程)。
  3. Node 装完版本还是旧的:说明装的是发行版自带的 node(旧源)。先 sudo apt remove nodejs,确认 NodeSource 源文件在 /etc/apt/sources.list.d/,再 update + install。
  4. 卸载后命令还在(java 卸了 java -version 还通):那是 alternatives 软链或另一个 JDK 目录。ls -l $(which java) 追链看真身;手装的在 /opt 自己删。
  5. 磁盘被 apt 缓存吃满:du -sh /var/cache/apt 查看体积,sudo apt clean 清空;已装包的 .deb 缓存删掉不影响已装软件。

面试常问

  • apt update 和 apt upgrade 的区别? update 只同步软件源的最新包索引到本地(不动任何软件);upgrade 依据本地索引,下载并升级已安装软件。所以 update 是 upgrade 的前置。对应 RHEL 系:dnf makecache 与 dnf upgrade。

  • apt 和 dpkg 的关系? dpkg 是底层包管理器,负责解包安装单个 .deb、登记文件清单(dpkg -L 查询);apt 是高层前端,自动解决依赖、从仓库下载安装。dpkg -i 装包缺依赖时要 apt install -f 兜底。

  • 如何在 Ubuntu 上安装指定版本的软件并防止被自动升级? apt list -a 包 查候选 → apt install 包=版本 精确安装 → apt-mark hold 包 锁定。解锁 unhold。生产冻结关键组件常用。

  • 说说你部署 Java 服务的完整环境安装过程。 一条主线:apt update → apt install openjdk-17-jdk-headless(java -version 验证)→ NodeSource 源装 Node 20(node -v)→ mysql-server(systemctl status 验证)→ nginx(后续反代)。要点:先刷索引、服务型软件装完验收自启状态、多版本 JDK 用绝对路径写进 systemd 避免 alternatives 歧义。

  • 软件包安装在系统里的哪些位置? 二进制多在 /usr/bin(软链)与 /usr/lib(库/JVM 在 /usr/lib/jvm);配置在 /etc(如 /etc/nginx、/etc/mysql);数据与日志在 /var(/var/lib/mysql、/var/log/nginx);文档在 /usr/share/doc。dpkg -L 包名 是权威清单。

自测三问

  1. apt update 后执行 apt install openjdk-17-jdk-headless,期间系统发生了哪几件事?
  2. 写出「安装 Node 20 并验证」的完整命令序列(Ubuntu 22.04),并说明为什么不能直接 apt install nodejs。
  3. 在 Rocky Linux 上完成「装 JDK17、看它装了哪些文件、锁定版本」需要哪些命令?

小结一句话

包管理 = 软件源(从哪来)+ 依赖与清单(怎么装)+ 版本控制(装哪个、锁不锁);Ubuntu 走 apt/dpkg,RedHat 走 dnf/rpm,装完必验版本与服务状态——环境安装从此告别「复制粘贴玄学」。

延伸

  • Ubuntu 官方 — Package Management
  • NodeSource 官方安装说明
  • 下一课预告:SSH 与密钥——每次登录输密码既烦又不安全。学会 ed25519 密钥对、authorized_keys、~/.ssh/config 别名,再把密码登录关掉,让 SSH 又快又硬。
加载本节练习…
← 上一课用户与 sudo下一课 →SSH 与密钥