Composer缓存配置失效的首要原因是COMPOSER_CACHE_DIR环境变量存在并覆盖所有config设置;其次必须显式配置cache-files-dir指向/files子目录,且路径须为绝对路径、手动创建并赋权。

composer config --global cache-dir 不起作用?先看 COMPOSER_CACHE_DIR
自定义缓存路径最常踩的坑,是只改了 cache-dir 却忘了环境变量。只要 COMPOSER_CACHE_DIR 这个环境变量存在(哪怕值为空),它就会直接覆盖所有 composer config 设置——包括 cache-dir 和 cache-files-dir。
验证方式很简单:
Linux/macOS 执行 echo $COMPOSER_CACHE_DIR,Windows PowerShell 执行 $env:COMPOSER_CACHE_DIR。
如果输出非空,哪怕只是空格或错误路径,Composer 都会跳过配置文件、fallback 到默认位置。
- CI/CD 流水线里常被 Jenkins/GitLab Runner 自动注入该变量,需检查构建日志是否含
export COMPOSER_CACHE_DIR=... - Docker 中若 base image 已设该变量,
docker run -e COMPOSER_CACHE_DIR=传空值也会触发 fallback - 临时调试时,用
unset COMPOSER_CACHE_DIR(Bash)或Remove-Item Env:\COMPOSER_CACHE_DIR(PowerShell)清掉再试
cache-files-dir 必须显式指向 files 子目录
cache-dir 只是父目录,真正存 ZIP 包的是 cache-files-dir,且它必须明确包含 /files(Linux/macOS)或 \files(Windows)子路径。只设 cache-dir 是无效的。
正确写法示例:composer config --global cache-dir /mnt/composer-cachecomposer config --global cache-files-dir /mnt/composer-cache/files
- 路径必须是绝对路径,
~和$HOME不会被解析,写进去就等于没设 - 目录需手动创建:
mkdir -p /mnt/composer-cache/files,并确保运行 Composer 的用户有读写权限 - 改完必须执行
composer clear-cache,否则旧缓存残留可能干扰验证
生产环境部署时路径仓库报错?别硬塞本地路径进 composer.json
用 "type": "path" 仓库做本地开发很爽,但一旦提交到 Git,生产环境 composer install 就会因路径不存在而中断——Composer 不会自动 fallback 到 Packagist,这是设计使然。
安全做法是把路径配置从 composer.json 移出,改用外部机制注入:
- 开发时用 Studio:它通过
studio.json管理本地包,不污染composer.json,且支持按环境启用/禁用 - CI/CD 构建阶段用脚本动态 patch:
jq '.repositories |= map(select(.type != "path"))' composer.json > composer.prod.json,再用该文件安装 - 完全避免路径仓库:用
composer global require安装开发工具,依赖包仍走 Packagist 或私有镜像
内网或离线环境怎么让不同机器用同一缓存路径?
关键不是“让路径一致”,而是“让缓存内容可复用”。即使路径相同,PHP 版本、composer.lock 哈希、源镜像地址三者只要有一个不同,Composer 就拒绝复用缓存文件。
真正可靠的做法是共享 cache-files-dir 目录本身(如 NFS 挂载、Docker volume),并确保:
- 所有机器使用相同 PHP 版本和扩展(尤其是 openssl、zlib)
-
composer.lock文件未被修改,且由同一台机器生成 - 全局配置统一镜像源:
composer config --global repo.packagist.org composer https://mirrors.aliyun.com/composer/ - 不依赖
COMPOSER_HOME,因为它的变更会连带影响auth.json和插件,增加同步复杂度
最后提醒一句:缓存路径能配对,不代表缓存一定命中。看到 Cache directory 输出正确,只是第一步;得进那个目录里真看到哈希命名的 .zip 文件,并确认 composer install 日志里出现 Downloading ... (cached),才算真正生效。


















