根本原因是打包机系统时间偏差超15分钟,导致composer拒绝解压;需用curl -i与date -r比对时间差,并通过timedatectl启用systemd-timesyncd校准,再清缓存、验证unzip版本。

为什么分布式打包机上 vendor 包总被重复下载
根本原因不是镜像配置或网络抖动,而是打包机之间系统时间偏差超过 15 分钟。Composer 在校验 dist ZIP 包时,会比对服务端响应头里的 Date 和本地系统时间,偏差超限时直接拒绝解压,哪怕包文件本身完整——此时你会看到 signature verification failed 或 filemtime(): stat failed,但实际是时间戳校验链断了。
如何确认是不是时间问题
别急着换镜像或清缓存,先做三件事:
- 在打包机上运行
curl -I https://packagist.org,记下响应头里的Date:值 - 运行
date -R,对比两者差值是否超过 ±15 分钟 - 执行
timedatectl status,重点看System clock synchronized: no和NTP service: inactive
只要任一条件成立,就是时间不准在作祟。Docker 容器、K8s Pod、CI runner 都继承宿主机时间,宿主机歪了,整条流水线全歪。
修复时间同步的实操步骤(Linux 打包机)
手动 date -s 是临时补丁,且易引发时区混乱。必须用 systemd-timesyncd 自动校准:
- 启用服务:
sudo timedatectl set-ntp true - 检查冲突:
ps aux | grep -E "(chronyd|systemd-timesyncd)";如果chronyd正在运行,先停用:sudo systemctl stop chronyd && sudo systemctl disable chronyd - 验证效果:
timedatectl timesync-status,server:字段应显示可信 NTP 源(如time1.aliyun.com),offset:应在 ±50ms 内 - 容器环境额外注意:启动时挂载宿主机时间文件,
-v /etc/localtime:/etc/localtime:ro
时间修复后还要注意什么
时间准了,不代表所有问题自动消失。以下两点容易被跳过:
- 旧缓存里可能存着因时间偏差导致校验失败而损坏的 ZIP 包,务必执行
composer clear-cache - CI 流水线中若用了
--prefer-dist,确保打包机上unzip工具版本 ≥ 6.0,否则解压含中文路径的 ZIP 会静默失败,表现为部分文件缺失
时间不准是底层依赖,它会让镜像、缓存、代理全部失效——修完时间再跑 composer install,才能真正回到“按 lock 还原”的预期行为。











