新买一台 Ubuntu VPS,SSH 登上去第一件事通常是:
sudo apt update
sudo apt install nginx docker.io curl
结果还没开始部署网站,apt 先报错了:
Failed to fetch
Temporary failure resolving
NO_PUBKEY
The repository does not have a Release file
Could not get lock /var/lib/dpkg/lock-frontend
dpkg was interrupted
You have held broken packages
这种问题很常见,也很烦。因为 apt 一坏,后面所有安装都被卡住:Nginx 装不了,Docker 装不了,PHP 装不了,连排查工具都可能装不了。
这篇不讲包管理器原理,按实战顺序来:先判断是网络/DNS、软件源、GPG Key、锁文件、半安装包,还是依赖冲突。不要一上来就复制“删除 lock 文件”的命令,很多时候那样会把问题搞大。
先跑:
sudo apt update
不要只看最后一行。把报错分成几类:
| 报错关键词 | 常见方向 |
|---|---|
Temporary failure resolving | DNS 解析失败 |
Failed to fetch | 网络、镜像源、IPv6、代理问题 |
404 Not Found | 软件源路径失效、系统版本 EOL |
NO_PUBKEY | 第三方源 GPG Key 缺失 |
Release file | 源不支持当前发行版或已废弃 |
Could not get lock | 另一个 apt/dpkg 正在运行 |
dpkg was interrupted | 上次安装中断,需要继续配置 |
held broken packages | 依赖冲突或版本被 hold |
先分类,再动手。apt 问题最怕“看都不看,直接删锁、换源、强删包”。
如果报:
Temporary failure resolving 'archive.ubuntu.com'
先确认是不是 DNS:
ping -c 3 1.1.1.1
ping -c 3 archive.ubuntu.com
如果 IP 能通、域名不通,先修 DNS,不要继续折腾 apt。可以临时测公共 DNS:
dig @1.1.1.1 archive.ubuntu.com
也可以看本机解析器:
resolvectl status
cat /etc/resolv.conf
如果你刚看过上一篇 DNS 解析文章,就知道这类问题应该先从 systemd-resolved、/etc/resolv.conf、云厂商 DNS 下发去查。
如果 DNS 正常,但 apt 下载慢或失败,试试 IPv4:
sudo apt -o Acquire::ForceIPv4=true update
有些 VPS IPv6 配了地址但路由不通,apt 会卡在 IPv6 上。长期修复要处理 IPv6 路由或软件源配置,不建议只靠临时参数糊住。
如果你看到:
404 Not Found
The repository does not have a Release file
先看系统版本:
lsb_release -a
cat /etc/os-release
再看源文件:
cat /etc/apt/sources.list
ls /etc/apt/sources.list.d/
Ubuntu 版本到 EOL 后,默认源可能不再提供对应路径。比如老版本 Ubuntu 需要切到 old-releases,或者更推荐升级到受支持版本。
不要盲目把网上的 jammy、noble、focal 混着复制。Ubuntu 22.04 是 jammy,24.04 是 noble。系统版本和源代号不一致,会引出一堆依赖冲突。
可以快速检查源里用了哪些代号:
grep -R "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/*.list
如果同一台机器里混了多个发行版代号,先停下来。混源是 apt 翻车的大户。
常见报错:
NO_PUBKEY ABCD1234EFGH5678
The following signatures couldn't be verified
这通常是第三方仓库的签名 key 没装好、过期,或者旧教程还在用废弃的 apt-key。
先找是哪一个源:
grep -R "第三方域名或仓库名" /etc/apt/sources.list.d/ /etc/apt/sources.list
现代做法通常是把 key 放到:
/etc/apt/keyrings/
然后源文件里用:
signed-by=/etc/apt/keyrings/example.gpg
例如 Docker 官方源大概会使用这种结构。不同软件的官方安装文档会给出对应命令。这里不要随便从论坛复制一个 keyserver 命令,因为你是在信任这个仓库能给系统安装软件。
修完后再跑:
sudo apt update
很多人遇到:
Could not get lock /var/lib/dpkg/lock-frontend
就直接:
sudo rm /var/lib/dpkg/lock-frontend
不推荐。
先看是不是系统自动更新正在跑:
ps aux | grep -E "apt|dpkg|unattended"
systemctl status apt-daily.service apt-daily-upgrade.service --no-pager
再看锁被谁占用:
sudo lsof /var/lib/dpkg/lock-frontend
sudo lsof /var/lib/dpkg/lock
如果是 apt.systemd.daily 或 unattended-upgrades 正在运行,通常等它结束更安全。
如果确认进程已经卡死,才考虑结束相关进程。结束前先确认没有正在安装重要包:
sudo fuser -v /var/lib/dpkg/lock-frontend
不要为了快而乱 kill。dpkg 中断后,后面还要修半安装状态。
如果报:
dpkg was interrupted, you must manually run 'sudo dpkg --configure -a'
那就按它说的做:
sudo dpkg --configure -a
这条命令会继续配置上次安装中断的包。
跑完再执行:
sudo apt --fix-broken install
sudo apt update
Ubuntu 社区和官方排障流程里也常用 dpkg --configure -a、apt --fix-broken install 这类命令修复中断状态。顺序很重要:先让 dpkg 把未完成的配置跑完,再处理依赖。
如果看到:
You have held broken packages
先看有没有包被 hold:
apt-mark showhold
如果确实有包被 hold,要确认为什么。不要盲目 unhold,可能之前是为了固定数据库、PHP、Nginx 版本。
查看包策略:
apt-cache policy 包名
模拟安装,不真正执行:
sudo apt install -s 包名
-s 是 simulation,适合先看 apt 准备装什么、删什么。
如果是依赖缺失:
sudo apt --fix-broken install
如果是混源导致版本互相打架,优先清理错误源,而不是强行安装。
可以用 dpkg 审计:
sudo dpkg --audit
也可以看异常状态:
dpkg -l | grep -E "^(..r|..U|..F|..H|iF|iU|iH)"
常见状态:
iU:包已解包但未配置iF:配置失败rc:包已删除但配置文件残留
对 iU、iF,通常先:
sudo dpkg --configure -a
sudo apt --fix-broken install
如果某个包一直配置失败,去看它的 postinst 报错、服务启动日志、磁盘空间,而不是直接强删。
apt/dpkg 需要写缓存、解包、配置文件。如果磁盘或 inode 满了,也会失败。
先看:
df -h
df -i
再清 apt 缓存:
sudo apt clean
如果 /boot 满了,常见是旧内核太多。先看当前运行内核:
uname -r
再看已安装内核:
dpkg -l 'linux-image*' | grep '^ii'
不要删除当前正在运行的内核。旧内核清理建议用 apt 的 autoremove 机制:
sudo apt autoremove
执行前看清楚它要删什么。
apt update 只是刷新软件包索引。真正安装时,还可能遇到依赖、冲突、磁盘、服务启动失败。
建议先模拟:
sudo apt install -s nginx
确认不会删除奇怪的包,再执行:
sudo apt install nginx
如果安装某个服务失败,比如 MySQL、Nginx、Docker,继续看对应服务日志:
systemctl status nginx --no-pager
journalctl -u nginx --since "30 minutes ago" --no-pager
有些包安装失败不是 apt 本身坏了,而是安装后的服务启动失败,dpkg 的 postinst 脚本返回错误。
遇到 apt/dpkg 报错,我一般按这个顺序:
sudo apt update
先看报错类型。如果是 DNS,先修 DNS。如果是锁:
ps aux | grep -E "apt|dpkg|unattended"
sudo lsof /var/lib/dpkg/lock-frontend
如果是中断:
sudo dpkg --configure -a
再修依赖:
sudo apt --fix-broken install
清缓存后更新:
sudo apt clean
sudo apt update
检查坏状态:
sudo dpkg --audit
apt-mark showhold
最后再安装目标软件:
sudo apt install -s 包名
sudo apt install 包名
这套流程比“删锁 + 强制安装”稳得多。
换源不是万能药,但有几种情况可以考虑:
- 当前镜像源长期 404 或超时
- VPS 所在地区访问官方源很慢
- 云厂商内网源更稳定
- 当前源不支持你的系统版本
换源前先备份:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
然后确认系统代号:
. /etc/os-release
echo "$VERSION_CODENAME"
源里的代号要和系统一致。不要 Ubuntu 22.04 用 24.04 的源,也不要 Debian 12 混 Ubuntu 源。
换完:
sudo apt update
如果报 GPG、Release file、依赖冲突,说明源还没配对。
有些情况继续硬修风险很高:
- 生产数据库正在运行,apt 想删数据库相关包
- 系统源混了多个发行版代号
/boot、/已经满了- dpkg 状态大量异常
- 你不知道某个被 hold 的包为什么被 hold
- 云厂商镜像太旧,系统已经 EOL
这时先做快照或备份,再继续。包管理器是系统底层,一次强删可能把 SSH、网络、数据库一起带崩。
- 已读完整 apt 报错,不只看最后一行
- DNS / 网络问题先用
ping、dig、resolvectl排除 - 软件源代号和系统版本一致
- 第三方源使用正确 GPG Key 和
signed-by - dpkg 锁先查进程,不直接删 lock 文件
-
dpkg was interrupted先跑dpkg --configure -a - 依赖问题再跑
apt --fix-broken install - 用
dpkg --audit检查半安装包 - 用
apt-mark showhold检查 hold 包 - 检查
df -h和df -i - 安装前用
apt install -s模拟 - 大改源或强删包前先做快照/备份
apt/dpkg 故障看起来一堆英文报错,其实大多能归类:网络解析、源配置、签名、锁、中断、依赖、磁盘。先归类,再按顺序修。只要不一上来乱删锁、乱换源、乱强删包,大多数 VPS 的 apt 都能救回来。
