唯一可靠方式是设置COMPOSER_CACHE_DIR环境变量;必须用绝对路径、提前创建目录并确保当前用户有读写权限,生效以composer diag输出为准,旧缓存需手动迁移。

COMPOSER_CACHE_DIR 环境变量是唯一可靠方式
直接改 composer.json 里的 cache-dir 完全无效;用 composer config --global cache-dir 虽然能写入配置,但容易因 JSON 格式错误、路径含波浪号 ~ 或权限问题静默失效。真正生效且可控的只有运行时环境变量。
必须满足三点:
-
COMPOSER_CACHE_DIR值必须是绝对路径,例如/home/alex/composer-cache,不能写~/composer-cache - 目录需提前创建:
mkdir -p /home/alex/composer-cache - 当前用户要有读写权限:
chown -R $USER:$USER /home/alex/composer-cache
设置后,composer update 会自动使用该路径,无需额外参数或重启 shell(只要变量在进程启动前已注入)。
验证是否真生效,别信 config 输出
composer config --global cache-dir 只显示配置值,不代表实际行为。真正决定缓存位置的是 composer diag 的输出行:
Cache directory: /home/alex/composer-cache
接着执行:ls -lh $(composer diag | grep "Cache directory" | cut -d' ' -f3),确认能看到新生成的 files/、repo/ 等子目录和文件。如果仍是 ~/.composer/cache 下的内容,说明环境变量没生效或路径权限不对。
CI/Docker 场景下常见静默回退
在 Docker 中设了 COMPOSER_CACHE_DIR=/tmp/composer-cache 却没效果?大概率是以下之一:
-
/tmp/composer-cache目录未mkdir -p,Composer 静默 fallback 到默认路径 - 容器以
root启动,但挂载的宿主机目录属普通用户,导致写入失败后同样静默回退 - 变量在
docker run中用-e传入,但未在ENTRYPOINT或命令执行前 export(尤其多层 shell 封装时)
建议在 CI 脚本开头加一句:echo "Cache dir: $(composer diag | grep 'Cache directory')",强制暴露真实路径。
旧缓存不会自动迁移,得手动处理
切换缓存目录后,Composer 不会把旧 ~/.composer/cache 里的包文件搬过去。如果你希望复用已有缓存(比如加速首次 update),必须手动同步:
rsync -a ~/.composer/cache/ /home/alex/composer-cache/
注意:只同步内容,不要覆盖 config.json 或 keys.tags.pub 等元数据文件。同步后检查权限,确保新目录下所有文件归属当前用户。
最易被忽略的是:缓存路径变更后,composer update 行为看似正常,但实际仍走默认路径——因为验证没做,或权限/路径写错导致静默 fallback。务必用 composer diag 看真实输出,再 ls 确认文件落地位置。


















