应通过COMPOSER_HOME隔离配置并组合hosts、镜像源与超时设置来规避系统DNS污染,务必执行composer clear-cache和--dry-run -vvv验证,Docker中需禁用resolvconf并强制写入DNS。

脚本里改/etc/resolv.conf不如用COMPOSER_HOME隔离配置
直接在部署脚本里echo "nameserver 114.114.114.114" > /etc/resolv.conf看似快,但会污染系统全局 DNS,且容器或无 root 权限环境根本不可行。更稳妥的做法是让 Composer 自己绕过系统 DNS 解析——通过预置 hosts + 镜像源组合,把域名解析“固化”在配置层。
关键点:Composer 本身不调用系统getaddrinfo()去查 DNS,它依赖 PHP 的curl或stream扩展,而这些底层仍受系统 DNS 影响。所以真正可控的入口是:hosts文件 + repo.packagist.org镜像 URL + http.timeout兜底。
- 脚本开头先写入临时 hosts(仅对当前用户生效):
echo "223.6.6.6 mirrors.aliyun.com packagist.org github.com" | sudo tee -a /etc/hosts - 紧接着设全局镜像:
composer config -g repo.packagist.org '{"type":"composer","url":"https://mirrors.aliyun.com/composer/"}' - 同步调高超时:
composer config -g http.timeout 600 - 最后加
COMPOSER_HOME=/tmp/composer-tmp避免和宿主配置冲突(尤其 CI 多任务并发时)
composer install前必须清缓存,否则hosts和镜像都不生效
Composer 会缓存packages.json元数据(含域名解析结果),哪怕你改了/etc/hosts或镜像源,旧缓存仍可能拉取 packagist.org 的原始地址。这不是 bug,是设计使然——它优先复用本地缓存减少网络请求。
脚本中漏掉这步,就会出现“明明配了阿里云镜像,日志却还显示Downloading https://packagist.org/packages.json”的诡异现象。
- 务必在
composer install前执行:composer clear-cache - CI 环境建议加
--no-cache参数:composer install --no-cache --no-dev --optimize-autoloader - 若用 Docker,把
~/.composer/cache挂载为 tmpfs 卷,避免磁盘 I/O 拖慢清理速度
脚本中检测 DNS 是否真被绕过,靠-vvv日志比ping更准
ping mirrors.aliyun.com返回 IP 并不能说明 Composer 就用了这个 IP——它可能被中间代理、SNI 过滤或 TLS 握手失败拦在半路。真正有效的验证方式是看 Composer 实际发起的 HTTP 请求目标。
在脚本里加一句诊断命令,失败时自动退出:
composer install --dry-run -vvv 2>&1 | grep -q "mirrors.aliyun.com" || { echo "ERROR: still hitting packagist.org"; exit 1; }
注意:--dry-run不实际下载,只解析依赖并打印请求链路;-vvv会暴露每一步的 URL 和响应头,包括重定向跳转。
- 如果日志里出现
GET https://packagist.org/packages.json或302 redirect to https://packagist.org,说明镜像配置写错键名(比如用了repos.packagist而非repo.packagist.org) - 如果卡在
Resolving dependencies阶段,问题不在 DNS,而是memory_limit或xdebug(此时应加COMPOSER_MEMORY_LIMIT=-1)
Docker 容器内脚本要额外处理--dns和/etc/resolv.conf冲突
在docker run里用--dns 8.8.8.8,不代表容器内composer install就一定走这个 DNS——Docker 会覆盖/etc/resolv.conf,但某些基础镜像(如php:alpine)自带resolvconf服务,会偷偷还原原配置。
最稳方案是:容器启动时禁用 resolvconf,并强制锁定 DNS,再运行 Composer 脚本。
- Alpine 镜像:
apk del resolvconf && echo "nameserver 223.5.5.5" > /etc/resolv.conf - Debian/Ubuntu 镜像:
systemctl disable --now systemd-resolved && echo "nameserver 114.114.114.114" > /etc/resolv.conf - 所有镜像都补一句:
composer config -g repo.packagist.org https://mirrors.aliyun.com/composer/,双重保险
别指望一次配置永久生效——容器每次重建都是干净环境,DNS 优化策略必须完整嵌入启动脚本,而不是只在构建阶段做。


















