返回博客

Debian slim 镜像里 apt 换源必须用 http 不能 https

国内服务器跑 Docker build,RUN apt-get install -y git 卡了五分钟没动静。直觉反应:换国内 apt 镜像源,把 deb.debian.org 替换成 https://mirrors.aliyun.com/debian。改完之后 build 终于动了,但随即抛出一行让人困惑的错误:

W: Failed to fetch https://mirrors.aliyun.com/debian/...
   Certificate verification failed: The certificate is NOT trusted
W: No system certificates available. Try installing ca-certificates.

等等——这是换 apt 源来装包,连证书都没有?

现象

  • Base 镜像是 node:20-bookworm-slim(或任意 *-slim 变体)。
  • RUN apt-get update && apt-get install -y git 挂起 3 分钟以上,无任何输出。
  • 将 sources 地址 sed 替换为 https://mirrors.aliyun.com/debian 后,apt-get update 报证书验证失败。
  • 进容器手动 cat /etc/apt/sources.list.d/debian.sources,看到的是含 Types:URIs:Suites: 字段的 deb822 格式,而不是老式的单行 sources.list。

根因

三个独立事实叠加在一起,才造成了这个死循环:

1. 默认 mirror 在国内极慢node:N-bookworm-slim 的默认源是 deb.debian.org,出国流量慢或被丢包,导致 apt-get update 长时间无响应。

2. Debian 12 换了配置格式:从 bookworm 开始,slim 镜像的 apt 源改用 deb822 格式,存放在 /etc/apt/sources.list.d/debian.sources,而不是以前的 /etc/apt/sources.list。很多老教程用 sed 替换 sources.list,其实改的是一个空文件或根本不存在的路径,完全无效。

3. slim 没有 ca-certificates:为了最小化镜像体积,slim 变体裁掉了 ca-certificates 包。结果是:想让 apt 通过 https 访问 mirror,需要 TLS 根证书;但根证书由 ca-certificates 提供;而 ca-certificates 又要通过 apt 安装——经典先有鸡还是先有蛋。

坑:slim 用 https mirror 是死循环

apt-get 需要 TLS 证书才能访问 https:// 源,而证书包(ca-certificates)本身要靠 apt-get 安装。在没有任何证书的 slim 容器里,把 mirror 换成 https 只会立即失败。

正解

换源时用 http:// 而不是 https://,同时注意要 sed 的是 deb822 格式文件:

FROM node:20-bookworm-slim AS builder
 
RUN sed -i 's|http://deb.debian.org|http://mirrors.aliyun.com|g' \
        /etc/apt/sources.list.d/debian.sources \
 && apt-get update \
 && apt-get install -y --no-install-recommends git ca-certificates \
 && rm -rf /var/lib/apt/lists/*
正解:http mirror + 改 debian.sources
  • sed 目标文件是 /etc/apt/sources.list.d/debian.sources(deb822),不是 sources.list
  • mirror 协议用 http://,绕开 TLS 证书依赖
  • 顺手装上 ca-certificates,后续层如有需要可切 https

为什么 http 是安全的:Debian 的包完整性依赖 apt-secure 的 GPG 签名校验,与传输层协议无关。https 在这里只防中间人看到你在下载什么包,不影响包的完整性保证。Debian 官方文档明确允许 http mirror。

可用的国内 mirror(均用 http)

http://mirrors.aliyun.com/debian        # 阿里云,稳定
http://mirrors.ustc.edu.cn/debian       # 中科大,稳定
http://mirrors.tuna.tsinghua.edu.cn/debian  # 清华
http://mirrors.huaweicloud.com/debian   # 华为云

aliyun 同时镜像了 debiandebian-security,一条 sed 替换 host 即可覆盖两条 URI,无需单独处理 -security 后缀。

附:非 slim 镜像可以用 https

如果 base 是 debian:bookwormnode:20(非 slim)等自带 ca-certificates 的镜像,就可以安全使用 https://mirrors.aliyun.com/debian。只有 slim 变体才有这个鸡蛋问题。

一句话外卖

在任何 Debian slim 容器里换 apt 源,协议必须是 http://,文件必须是 /etc/apt/sources.list.d/debian.sources——slim 没有 ca-certificates,https 是死路。