2026/10/22 2:55:57

Ubuntu 24.04 配置 Docker 官方源遇 GPG 报错?密钥缺失与 NO_PUBKEY 全修复

Ubuntu 24.04 配置 Docker 官方源遇 GPG 报错?密钥缺失与 NO_PUBKEY 全修复 Ubuntu 24.04 发布之后不少人在配置 Docker 官方仓库时栽了跟头。明明照着教程一步步来结果apt update直接甩出一段GPG error要么是NO_PUBKEY要么是The following signatures couldnt be verified。说真的这类问题我在 Ubuntu 20.04、22.04 上都遇到过但 24.04Noble Numbat上出现的频率尤其高而且报错形态更多。这篇东西不打算把官方文档复读一遍而是直接聊清楚为什么你会撞上 GPG 密钥缺失、怎么定位具体原因、有哪些能落地的解决办法以及每一步操作背后的逻辑。不管你是刚接触 Linux 的新手还是偶尔给服务器装环境的开发者照着做基本都能把源修好。1. 先搞清楚你遇到的到底是哪种 GPG 报错盲修是最浪费时间的事。很多人一看到GPG error就开始搜命令结果复制了一堆不匹配的解决方案越修越乱。所以第一步先学会分辨报错类型。1.1 最常见的两类报错画面第一类是在apt update时出现类似这样的信息W: GPG error: https://download.docker.com/linux/ubuntu noble InRelease: The following signatures couldnt be verified because the public key is not available: NO_PUBKEY 4D1A1B4E注意结尾的NO_PUBKEY后面跟着一串十六进制字符。这串字符是公钥的短 ID意思是系统在本地信任链里找不到对应的公钥因此无法验证仓库元数据的签名。第二类是在你手动添加密钥时直接失败gpg: keyserver receive failed: No data curl: (22) The requested URL returned error: 404 gpg: no valid OpenPGP data found.这类报错说明密钥文件本身没有正确下载或者下载到的是一个 HTML 错误页面而不是真正的 .asc 文件。很多教程直接在命令里用curl ... | gpg --dearmor管道一气呵成一旦中间某一环出了问题你根本看不到具体是哪步失败的。1.2 为什么 Ubuntu 24.04 上触发概率更高Ubuntu 24.04 是当时比较新的版本Docker 官方仓库对这个版本的 Release 文件和 InRelease 文件都正常提供理论上不该有密钥问题。但实际踩坑的人多主要原因是网上流传的教程大量是给 20.04、22.04 写的里面使用的密钥 ID、仓库路径、signed-by 写法都有细微差别。另一个原因是从 Ubuntu 22.04 开始apt-key已经明确定位为废弃工具到了 24.04 很多教程还没来得及更新仍在使用老式写法于是报错集中爆发。还有一个容易被忽略的点Ubuntu 24.04 的代号是noble对应 Docker 源的路径应该是https://download.docker.com/linux/ubuntu noble stable。有些教程写成focal或jammy系统找不到对应的仓库索引也会以 GPG 签名验证失败的形式表现出来需要一并排查。2. 问题根因Docker 官方密钥机制的变更解决问题不能只看表面命令得知道为什么会出现密钥缺失。GPG 这套机制本身并不复杂Docker 仓库的变更也只是顺应了整个 Debian/Ubuntu 生态的演进。2.1apt-key的废弃是历史必然早年添加第三方 apt 源的标准操作是curl ... | apt-key add -。apt-key会把密钥直接塞进/etc/apt/trusted.gpg或者/etc/apt/trusted.gpg.d/里。缺点很明显所有第三方源共享一个信任库任何一个源被攻破等于所有源都暴露风险。而且apt-key没有提供方便的撤销机制密钥一旦泄露很难单独剔除。Debian 和 Ubuntu 很早就开始推动新的信任方式把密钥以独立文件形式放到/etc/apt/keyrings/然后在源配置里用signed-by指定该文件。Docker 官方文档其实也更新了这种写法但搜索到的很多中文教程仍是老路子这是大多数人踩坑的直接原因。2.2 Docker 仓库密钥文件的两种形态Docker 官方仓库公开的密钥文件既有.ascASCII armored格式也可能在新旧页面里用.gpg二进制格式。官方安装文档里用的命令是sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc注意这里的重点是下载后直接保存为docker.asc没有再执行gpg --dearmor转成二进制。apt 本身能直接读取 ASCII armored 格式的 OpenPGP 公钥所以很多人用老教程的gpg --dearmor反而可能因为中间多了一次管道处理而失败。2.3 网络环境和下载链路对密钥获取的影响密钥缺失还有一种常见的幕后原因是网络不通。比如某些网络环境下访问download.docker.com不稳定或者代理配置导致 cURL 请求被拦截。这种情况下报错不一定直接说是网络问题而是表现为gpg: no valid OpenPGP data found。因为 cURL 可能返回了空文件或一个连接重置的错误。所以排查时不要只盯着 GPG 本身先确认密钥文件能否独立下载成功。把这个前提放在前面能省下很多无头绪的排查时间。3. 三种可落地的解决办法根据报错类型和现场环境可以选用不同的解法。我按推荐程度排个序。3.1 方案一手动拉取并转换密钥文件推荐这个方案最稳不依赖apt-key也完全符合 Ubuntu 24.04 的官方推荐方式。先把目录建好权限设为 755让普通用户可以读取但只有 root 能写入sudo install -m 0755 -d /etc/apt/keyrings然后下载密钥。这里不推荐直接管道给其他命令建议先下载到本地校验无误后再安装curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /tmp/docker-key.asc如果下载成功可以用file命令看一眼文件类型file /tmp/docker-key.asc正常会输出类似PGP public key block Public Key (Old)的信息。如果输出显示HTML document基本可以断定网络被劫持或代理返回了错误页面。确认无误后安装到 keyrings 目录sudo install -m 0644 /tmp/docker-key.asc /etc/apt/keyrings/docker.asc这里为什么用0644因为 apt 在读取这个文件时可能以非 root 用户身份进行权限过严会导致后续 apt update 报“权限不够”。Docker 官方文档通常要求ar其实就是确保其他用户可读。接下来添加仓库源。Ubuntu 24.04 的源文件建议放在/etc/apt/sources.list.d/下以.list或.sources结尾。用传统.list写法echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null这个命令里用了$(. /etc/os-release echo $VERSION_CODENAME)自动获取当前系统的代号对于 Ubuntu 24.04 来说就是noble不用手动写死也避免复制别的教程时把 jammy 写进去的尴尬。最后执行sudo apt update此时不应该再出现 NO_PUBKEY 或者签名校验失败的错误。3.2 方案二借助 keyserver 补拉公钥如果你只是遇到NO_PUBKEY 4D1A1B4E这种报错系统本地缺少公钥还可以直接从公钥服务器拉取。这种情况通常发生在旧配置里没有指定signed-by或者signed-by指向的文件内容不对、为空。命令格式sudo gpg --keyserver keyserver.ubuntu.com --recv-keys 4D1A1B4E这里的公钥短 ID 要和报错里的完全一致。如果系统里已经存在一个 keyring 文件也可以导入到该文件里gpg --keyserver keyserver.ubuntu.com --recv-keys 4D1A1B4E gpg --export 4D1A1B4E | sudo tee /etc/apt/keyrings/docker.asc /dev/null注意这种方式的局限如果你面对的是原仓库签名密钥已经更换、旧公钥彻底失效的情况单纯补拉公钥解决不了因为新文件是用新公钥签名的旧公钥再齐也没用。keyserver 方式更适合解决“本地没有但公钥本身存在”的情况。3.3 方案三旧式apt-key急救法仅限临时场景我写这个方案不是推荐大家用而是考虑到有些服务器环境里存在历史脚本一时改不了。老办法是curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -执行后会提示 apt-key 已废弃的警告但操作本身仍能完成。随后 apt 会把这个密钥加入全局信任链一般能暂时消除 NO_PUBKEY。不过这个方案的问题前面提过全局信任不好撤销。另外在新版 Ubuntu 上apt-key 还在但已被标记为 deprecated不能保证未来某个版本移除后你的自动化脚本还能跑。所以它只配作为应急手段等有空闲时还是要迁移到 signed-by 方案。4. 完整实操从零到能正常 apt update光列命令不够我把整个流程串起来按步骤走一遍。这套流程在 Ubuntu 24.04 Docker 官方仓库配置里是比较完整的可以直接抄。4.1 清理掉脏仓库配置如果你已经照着某些教程配置过apt update 一直在报错先把旧的源文件和密钥文件清掉避免残留干扰。检查一下ls -l /etc/apt/sources.list.d/把带docker字样的文件列出来看内容。如果里面的路径明显不对或者有重复的 deb 行直接删掉重建sudo rm -f /etc/apt/sources.list.d/docker.list同时把旧密钥文件也整理一下ls -l /etc/apt/keyrings/如果你之前建过 docker.asc 或 docker.gpg但内容已经不是当前官方密钥也删掉或者用新内容覆盖。4.2 重新添加 Docker 官方仓库按正常顺序来。先安装必要工具sudo apt update sudo apt install -y ca-certificates curlca-certificates是 HTTPS 证书信任链的基础不能省。如果没有它curl 访问 Docker 官网时可能直接报 SSL 证书错误。接着创建 keyrings 目录并下载密钥sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc这一步如果失败curl 的-f参数会让命令在收到 404 或 500 时直接返回退出码而不是保存一个错误页面。所以看到“命令执行成功”但文件大小异常时还是要手动检查一下文件类型我在 3.1 里给过file命令。然后写入源echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null注意$(. /etc/os-release echo $VERSION_CODENAME)这一长串是在当前 shell 里执行的需要确保这条命令不是用 sudo 直接执行否则 sudo 环境下可能会找不到系统变量。用echo | sudo tee的写法是安全的因为变量是在执行echo之前由当前用户解析的。4.3 用 apt update 验证结果配置完成后执行sudo apt update正常情况下输出里应该能看到Get:3 https://download.docker.com/linux/ubuntu noble InRelease [48.9 kB]后面还会继续拉取stable的包索引没有报错。此时就说明密钥配置生效了。再验证一下能否正常安装 Docker 核心包apt-cache policy docker-ce如果输出里出现Candidate版本且指向 docker.com 的源就代表整个链路都通了。接着可以放心安装 docker-ce、docker-ce-cli、containerd.io。5. 常见问题与排错速查这部分写给那些按照流程走完但仍然报错的人。我按错误特征列几个高频场景附上排查思路。5.1 NO_PUBKEY 反复出现如果你确认密钥文件存在、路径也写对apt update 还是报 NO_PUBKEY先排查一个细节源文件里的signed-by路径是否指向了真实存在的文件以及 apt 运行用户是否有读取权限。执行ls -l /etc/apt/keyrings/docker.asc cat /etc/apt/keyrings/docker.asc | head -n 2如果文件不存在回到 3.1 重做。如果文件存在但 cat 输出显示二进制乱码说明你下载的是二进制 .gpg 但内容可能损坏。遇到这种情况重新下载一遍不要用旧缓存。还有一种情况同时存在多个源文件引用了同一个 Docker 源其中一个写了对的密钥另一个写错了。仔细看/etc/apt/sources.list.d/下是否有多个 docker 相关文件只留一个有效的。5.2 提示 unsigned 或仓库没有 Release 文件这类报错通常是源配置里的仓库路径写错了系统在对应目录下找不到 InRelease 或 Release 文件被迫把它当成无签名仓库处理。例如写成deb https://download.docker.com/linux/ubuntu noble stable少了[arch... signed-by...]段apt 会尝试用默认信任方式验证一旦本地没有 Docker 密钥就会报未签名。排查方法是手动访问一下仓库地址curl -fsSL https://download.docker.com/linux/ubuntu/dists/noble/InRelease如果能看到文件内容说明仓库路径没问题如果 404把noble改成jammy或者检查是否多写了层级。还有一点Docker 源对 24.04 是支持noble的但部分教程写的$(lsb_release -cs)获取到的可能是noble这个没问题。如果你在 WSL 环境里操作lsb_release -cs可能返回的是focal或jammy因为 WSL 的发行版标识不一定和主机一致需要人工确认。5.3 下载密钥时提示连接超时或证书错误这种情况多见于跨境网络、公司代理或防火墙限制。先确认不是 DNS 问题curl -v https://download.docker.com/linux/ubuntu/gpg -o /dev/null如果卡在连接阶段可以更换 DNS 或者检查系统代理设置。如果返回的是代理的证书说明 shell 环境变量里设置了http_proxy/https_proxy但代理证书没有被系统信任。处理办法是让 curl 临时忽略环境变量curl --noproxy * -fsSL https://download.docker.com/linux/ubuntu/gpg -o /tmp/docker-key.asc如果公司网络确实无法直连官方源另一种可行思路是使用镜像源。但要注意镜像源的密钥文件也要一并替换不能混用 Docker 官方密钥和国内镜像源否则同样会出现签名验证失败。5.4 其他容易踩的坑第一个坑在 Ubuntu 24.04 上使用apt-key时虽然命令还能执行但输出会有一行明显的 deprecation 警告。有些自动化脚本会把这个警告当成错误处理导致脚本中断。建议趁早改造。第二个坑/etc/apt/keyrings/目录权限设成了 700apt 以_apt用户读取时没权限。设置成 755 即可这也是官方文档里 install 命令用0755的原因。第三个坑用.sources格式deb822 格式的人越来越多。这种格式里Signed-By字段支持直接写/etc/apt/keyrings/docker.asc但也支持内嵌密钥内容。很多人从.list抄配置时忘了改字段名把signed-by小写写法留在.sources文件里结果不被识别。如果要用.sources格式是Types: deb URIs: https://download.docker.com/linux/ubuntu Suites: noble Components: stable Signed-By: /etc/apt/keyrings/docker.asc第四个坑下载密钥后有些人会顺手执行sudo gpg --dearmor再保存为.gpg文件。这本身没问题但如果下载的文件其实已经是 ASCII armored 格式gpg --dearmor转换出来也是合法的二进制公钥理论上能用。问题出在一部分教程把命令写成curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg一旦 curl 失败或输出为空gpg --dearmor会生成一个零字节文件apt 读不到公钥自然报 NO_PUBKEY。所以不管用什么命令中间过程一定要留出校验环节。6. 一些个人的建议聊几个我自己的习惯供参考。密钥文件我倾向直接用.asc不转.gpg。apt 两种都能识别但.asc是文本格式肉眼能看内容出问题时诊断方便。另外.asc文件即使被意外截断gpg 校验时能给出更明确的错误信息比纯二进制文件友好。源文件尽量用一个独立文件管理不要塞到/etc/apt/sources.list主文件里。主文件是系统级配置升级时可能被覆盖或产生冲突。独立文件放到/etc/apt/sources.list.d/更新系统时不容易被误改卸载相关软件包时删一个文件就行干净利落。还有一点不要只盯着密钥问题。很多人修完 GPG 报错后下一步 apt install docker-ce 又遇到Package docker-ce is not available然后又开始抓狂。这种情况大概率是源添加成功但stable组件名写错或者架构写错。在源配置里确认[archamd64]和你的dpkg --print-architecture输出一致同时确认系统版本代号正确90% 的后续问题都能避免。最后分享一个小技巧如果你需要在多台 Ubuntu 24.04 机器上重复配置 Docker 源与其每次手动敲命令不如把这套操作整理成一个 shell 脚本脚本里自带密钥下载校验、源文件写入、apt update 三步。但脚本里不要用apt-key也不要在curl后面直接跟gpg --dearmor而是严格按照先下载到临时文件、检查文件类型、再安装的顺序写。这样哪怕某台机器网络异常脚本也会在错误地点停下来而不是生成一个空密钥文件污染后续步骤。我自己的经验是这类“半自动化”脚本比纯手动要稳得多排查时也容易定位问题出现在哪台机器、哪一步。