答案是Composer默认先尝试IPv6解析,超时1–3秒后才fallback至IPv4,上百包叠加导致几分钟无响应;应换国内镜像源、调高PHP default_socket_timeout、切换系统DNS并清缓存。

为什么Composer卡在DNS解析阶段不报错
不是网络慢,是默认先查 IPv6 地址,超时(通常 1–3 秒)再 fallback 到 IPv4。上百个包叠加,就是几分钟无响应。验证方法:curl -v https://packagist.org 2>&1 | grep "Connected to",如果看到 Connected to packagist.org (2a03:2880:...) 后卡住,基本就是它。
换镜像源是最直接的 DNS 加速手段
国内直连 packagist.org 本身 DNS 解析就慢,且常被污染或拦截。换阿里云镜像后,域名变成 mirrors.aliyun.com,解析走的是国内稳定 DNS,几乎秒回。
- 执行
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/(注意末尾必须有/) - 旧版 Composer 1.x 需用
composer config -g repos.packagist '{"type":"composer","url":"https://mirrors.aliyun.com/composer/"}' - 检查是否生效:
composer config -g repo.packagist输出应为镜像 URL,不是https://packagist.org - 项目级
composer.json中若定义了repositories,会覆盖全局配置,得手动删或改
系统级 DNS 设置必须同步调整
Composer 依赖 PHP 的 file_get_contents 或 cURL,而它们底层受 PHP default_socket_timeout 和系统 DNS 影响。常见坑是:你设了 http.timeout 600,但 PHP 的 default_socket_timeout 还是默认 60 秒,连接会在 60 秒被硬掐断。
- 查当前值:
php -i | grep default_socket_timeout - 临时调高:
php -d default_socket_timeout=600 $(which composer) install - 永久修改:在
php.ini中设default_socket_timeout = 600 - 系统 DNS 建议换为
8.8.8.8或223.5.5.5,然后清缓存(sudo dscacheutil -flushcache或ipconfig /flushdns)
容器内运行时 DNS 配置容易被忽略
Docker 容器默认继承宿主机 /etc/resolv.conf,但很多内网环境的宿主机 DNS 不可靠,导致 composer install 在容器里反复失败。
- 不要用默认 bridge 网络——它不保证 DNS 可控
- 在
docker-compose.yml服务中显式加:dns: ["192.168.10.5", "8.8.8.8"]和dns_search: ["svc.cluster.local"] - 避免同时写
network_mode: host和dns字段——host 模式下dns被完全忽略 - CI 环境中建议额外加
COMPOSER_HTTP_TIMEOUT=1200和COMPOSER_MEMORY_LIMIT=-1,防止双重限制
DNS 解析延迟最隐蔽的地方在于:它不报错、不中断、只是“卡住”,而且问题会随依赖数量线性放大。调一个参数往往不够,得同时动镜像源、PHP 超时、系统 DNS、容器网络四层。











