根本原因是composer对http和https请求使用独立代理路由,仅配http-proxy而缺https-proxy时,https请求会直连被阻断;必须同时配置两个字段且均以http://开头,缺一或格式错误均导致静默失败。

为什么内网 Composer 代理配置后仍连不上 Packagist
根本原因不是代理没开,而是 Composer 对 HTTP 和 HTTPS 请求走两套完全独立的代理路由:只配 http-proxy,https-proxy 缺失时,所有对 https://repo.packagist.org 的请求会 fallback 到直连——而内网通常直接阻断该域名的出向连接,结果就是卡在 “Loading composer repositories”,无报错、无超时提示。
必须同时设置两个字段,且值都得是 http:// 开头(哪怕代理本身监听 TLS 端口):
composer config -g http-proxy http://127.0.0.1:8080composer config -g https-proxy http://127.0.0.1:8080
漏掉任意一个,或把 https-proxy 写成 https://127.0.0.1:8080 或不带协议头,都会静默失败。验证命令:composer config -g --list | grep -E "(http|https)-proxy",必须看到两行且格式正确。
NTLM 代理(如 Windows 域环境)下 Composer 完全不工作
Composer 原生不支持 NTLM 认证,设了 http-proxy 也只会收到 407 Proxy Authentication Required 或 Unable to connect to http://repo.packagist.org。这不是配置问题,是协议层不兼容。
唯一可行方案是引入本地中转代理,让它们处理 NTLM,再暴露标准 HTTP/HTTPS 代理端口给 Composer:
- Windows 推荐用
cntlm或px,监听127.0.0.1:3128 - Linux/macOS 可用
cntlm或mitmproxy(需额外配置认证逻辑) - 然后 Composer 配置指向本地:
composer config -g https-proxy http://127.0.0.1:3128
临时验证是否是 NTLM 问题:curl -x http://127.0.0.1:3128 -I https://packagist.org/packages.json。如果 curl 同样返回 407,说明中转代理没配好,别浪费时间调 Composer 配置。
代理 + 镜像源能不能共存?会冲突吗
不能共存,会相互干扰。一旦你执行了 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/,Composer 就不再访问 repo.packagist.org,自然也就绕过了你配的 https-proxy;反之,若代理已生效,再切镜像源反而可能因 DNS 或证书链不一致导致失败。
选哪个取决于你的网络策略:
- 纯内网无外网权限 → 必须用私有仓库(Satis/Nexus)或离线模式,代理无效
- 有可控代理(如公司统一出口)→ 优先配代理,不用镜像
- 代理不可靠或仅临时使用 → 切国内镜像源更稳,命令:
composer config -g repos.packagist composer https://mirrors.tencent.com/composer/
注意键名差异:repo.packagist(旧版)和 repos.packagist(新版)在不同 Composer 版本中行为不一致,建议统一用 repos.packagist 并确认版本 ≥ 2.2。
内网穿透后 Composer 还是慢,怎么定位瓶颈
现象一致(卡住、无响应),但问题可能发生在任意一层:本地代理进程未启动、防火墙拦截 CONNECT 请求、中转代理 TLS 证书不受信任、甚至 Docker 容器内 DNS 解析异常。
分步排查比瞎试更快:
- 先确认代理进程活着:
netstat -tuln | grep :8080(Linux/macOS)或netstat -ano | findstr :8080(Windows) - 绕过 Composer,用 curl 直连测试:
curl -v -x http://127.0.0.1:8080 https://packagist.org/packages.json,看是否返回 200 或明确错误(如 502、timeout) - 如果 curl 成功但 Composer 失败,大概率是 CA 证书问题:PHP cURL 默认不信任代理自签证书,需加
COMPOSER_CAFILE或临时关校验(不推荐) - Docker 场景下,检查容器是否用了 host 网络模式,或
/etc/resolv.conf是否被覆盖导致 DNS 失效
真正容易被忽略的是:即使代理通了,Composer 在解析 packages.json 后还会为每个包发起独立的 Git 克隆或 ZIP 下载请求——这些请求同样要走代理或镜像,而很多私有 Git 仓库地址(如 git@internal-git.com)并不在镜像覆盖范围内,必须单独配置 vcs 类型仓库。











