根本原因是VCS包使用独立的cache-vcs-dir路径,不随cache-dir自动变更;必须显式配置cache-vcs-dir为绝对路径、手动创建目录并授权,且需验证composer diag输出及-vvv日志中Cloning into路径是否更新。

Composer绑定企业VCS后,cache-dir改了但下载仍走默认路径?
根本原因不是缓存目录没生效,而是企业 VCS(如私有 GitLab、Bitbucket Server)的包下载行为绕过了 cache-files-dir 的常规路径逻辑——Composer 对 VCS 包默认使用 cache-vcs-dir 存储克隆副本,而这个目录不随 cache-dir 自动联动。
常见现象:你执行了 composer config --global cache-dir /data/composer-cache,但 composer install -vvv 日志里仍看到 Cloning into '/home/user/.composer/cache/vcs/https---gitlab.example.com-my-group-my-package/'。
-
cache-vcs-dir必须单独配置,且路径需手动创建、设对权限(尤其 CI 中用非 root 用户运行时) - 企业 VCS 的包(
"type": "vcs"或通过repositories添加的 Git 地址)不会走cache-files-dir,哪怕你配了 ZIP 下载 fallback - 若同时用了
cache-read-only true,cache-vcs-dir必须可读且已含历史克隆;否则 Composer 会跳过缓存直接 clone,造成重复拉取
重置 VCS 缓存目录的三步操作(顺序不能错)
不是只改 config 就完事。VCS 缓存有状态残留,必须清旧 + 配新 + 验证路径实际被写入。
- 先停掉所有正在运行的 Composer 进程(尤其 IDE 内嵌终端、CI 构建中未退出的 job)
- 删旧缓存:
rm -rf $(composer config --global cache-vcs-dir);若报错或为空,用composer config --global cache-vcs-dir确认当前值再删 - 配新路径:
composer config --global cache-vcs-dir /data/composer-cache/vcs(注意:路径必须是绝对路径,末尾不加/files或/repo) - 手动创建并授权:
mkdir -p /data/composer-cache/vcs && chmod 755 /data/composer-cache/vcs
COMPOSER_CACHE_DIR 环境变量对 VCS 缓存的影响
这个变量优先级最高,但它只控制 cache-files-dir 和 cache-repo-dir,**不控制 cache-vcs-dir**。很多团队在 CI 中挂载共享缓存时踩坑就在这里。
- 设了
COMPOSER_CACHE_DIR=/mnt/cache→cache-files-dir自动变成/mnt/cache/files,但cache-vcs-dir仍是旧值 - 验证方式:运行
composer diag,重点看cache-vcs-dir行输出是否为你期望的路径 - 如果必须统一前缀,得显式覆盖:
composer config --global cache-vcs-dir /mnt/cache/vcs,不能依赖环境变量推导
验证 VCS 缓存是否真走新路径
别信 config 输出,要亲眼看到日志里出现新路径的写入动作。
- 执行一次带 VCS 包的安装:
composer install -vvv | grep "Cloning into" - 正确输出应为:
Cloning into '/data/composer-cache/vcs/https---gitlab.example.com-xxx/' - 如果仍看到
.composer/cache/vcs/,说明cache-vcs-dir没生效——大概率是 config 命令执行用户和实际运行用户不一致(比如用 root 配的,但 CI 用www-data跑),得检查属主:sudo chown -R www-data:www-data /data/composer-cache/vcs - Windows 下注意路径分隔符:PowerShell 中用反斜杠,但
composer config内部处理仍认正斜杠,建议统一用composer config --global cache-vcs-dir "D:/composer-cache/vcs"
关键点在于:VCS 缓存路径和其他缓存路径是解耦的,改一个不等于全改。企业场景下常因权限、用户上下文、环境变量干扰导致“以为重置了,其实还在用旧目录”。











