composer容器内配代理必须同时设http-proxy和https-proxy字段,仅配http-proxy会导致https请求直连超时;https-proxy值须为http://开头,配置需全局生效并正确挂载,ntlm代理需中转工具。

Composer容器内配代理必须设http-proxy和https-proxy两个字段
只配http-proxy,composer install会卡在“Loading composer repositories”,因为Packagist全量走HTTPS,而Composer对HTTP和HTTPS代理是分开路由的:http-proxy只管HTTP请求,https-proxy才负责建立CONNECT隧道。漏掉任一字段,HTTPS请求就fallback直连,最终超时或502,且无明确报错。
实操要点:
-
https-proxy的值必须是http://开头(哪怕代理本身监听TLS端口),例如http://127.0.0.1:8080;填成https://或漏协议头都会静默失败 - 命令必须加
-g(等价--global),否则配置只写入当前项目composer.json,换目录/换容器就失效 - 密码含
@、/、:要URL编码,比如pa@ss/word→pa%40ss%2Fword,可用php -r "echo rawurlencode('pa@ss/word');"快速生成 - 验证是否生效:运行
composer config -g --list | grep -E "(http|https)-proxy",确认两行都存在且格式正确
Docker中挂载Composer全局配置和缓存目录
在容器里反复重装依赖很慢,核心是没复用宿主机的~/.composer目录。直接挂载整个目录风险高(权限、路径冲突),推荐只挂载关键子目录:
实操建议:
- 挂载
~/.composer/auth.json(含私有仓库凭证)和~/.composer/config.json(含代理设置),用volumes映射到容器内/root/.composer/对应路径 - 挂载
~/.composer/cache到/root/.composer/cache,避免每次下载重复包;注意宿主机该目录需存在且可写 - Windows/macOS用户注意:
%APPDATA%\Composer\config.json或~/Library/Application Support/Composer/config.json才是真实路径,别硬套~/.composer - 若用
user:指定非root用户(如user: "1001:1001"),挂载点要对应改为/home/app/.composer,并确保宿主机目录属主匹配
docker-compose中代理配置的生效边界
代理不是写进docker-compose.yml的environment就能用——Composer根本不读HTTP_PROXY环境变量,只认自己的http-proxy和https-proxy配置项。
常见踩坑点:
- 在
environment里写HTTP_PROXY=http://...纯属无效,删掉省得误导 - 用
docker-compose run --rm php composer install时,代理配置来自容器内/root/.composer/config.json,不是宿主机当前shell的环境变量 - 多阶段构建中,构建阶段(builder)也得单独配代理;如果只在运行阶段镜像里配,构建时仍会因网络问题失败
- CI场景下,建议把
composer config -g命令写进Dockerfile的RUN指令,而非依赖挂载,避免权限或路径不可控
NTLM代理环境下必须引入中转层
公司域环境常用NTLM代理(比如Windows AD集成),Composer原生不支持,设了http-proxy也会直接返回407 Proxy Authentication Required或Unable to connect。
绕过方案只有引入中转代理工具:
- Linux/macOS推荐
cntlm或px,监听127.0.0.1:3128并处理NTLM认证,再让Composer连这个本地地址 - Windows可装
cntlm服务,配置Proxy 192.168.1.100:8080和Username/Domain/Password,然后Composer配http-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源码或加PHP扩展解决——这是协议层限制,必须靠中转代理落地
config.json文件,并且路径、权限、协议格式全部对得上。任何一层脱节(比如挂载错路径、用户UID不一致、https-proxy写成https://),都会导致静默失败——既不报错,也不工作。











