缓存目录必须显式分离 files 和 repo:Composer 默认混存,需用 cache-files-dir 和 cache-repo-dir 独立配置;二者须物理隔离,且仅支持全局/用户级配置,不可写入 composer.json;备份时建议清空 repo 缓存后仅备份 files 目录。

缓存目录必须显式分离 files 和 repo
Composer 默认把包文件和元数据混存在同一级缓存目录下(如 ~/.composer/cache),但备份时若只复制整个目录,会因路径硬编码或权限问题导致恢复失败。真正可迁移的备份策略要求二者物理隔离。
-
cache-dir配置仅指定根目录,不控制内部结构;要分离,必须用cache-files-dir和cache-repo-dir两个独立配置项 - 例如:执行
composer config -g cache-files-dir ~/.composer/cache-files和composer config -g cache-repo-dir ~/.composer/cache-repo - 配置后运行一次
composer clear-cache,否则旧缓存仍留在默认位置,新路径不会被自动填充 - 注意 Windows 路径中的反斜杠需转义或用正斜杠,否则
composer diagnose会报Invalid cache directory
composer.json 里不能写死缓存路径
项目级 composer.json 不支持 cache-files-dir 或 cache-repo-dir 字段——这些是全局或用户级配置,写进项目配置会被忽略,且可能干扰 CI 环境变量注入逻辑。
- 所有缓存路径配置必须通过
composer config -g或composer config(无-g)写入config.json,而非composer.json - 检查是否误写:运行
composer config --list | grep cache,输出中若出现cache-files-dir且来源是system或global,说明配置生效;若来源是local,说明它被错误塞进了当前项目配置 - 已误写的清理命令:
composer config --unset cache-files-dir(无-g)和composer config --unset cache-repo-dir
备份时忽略 cache-repo 的过期元数据更安全
元数据缓存(cache-repo)包含包列表、版本映射等,但它的 TTL 默认是 15 天(cache-files-ttl 控制的是包文件)。直接备份过期的 repo 缓存,恢复后首次 composer update 可能触发大量 404 或版本错乱。
- 推荐做法:备份前先清空元数据缓存,再备份
cache-files目录 —— 即只保留“可复用的包文件”,元数据交由 Composer 自行刷新 - 命令组合:
composer clear-cache --no-interaction && cp -r ~/.composer/cache-files /backup/composer-files-$(date +%Y%m%d) - 若必须备份元数据(如离线环境),需同步记录生成时间,并在恢复后手动设置
cache-files-ttl为极大值(如31536000秒),避免 Composer 自动丢弃
CI/CD 中挂载缓存需分别处理两个目录
Docker 或 GitHub Actions 中用 volume 挂载 Composer 缓存时,若只挂载 ~/.composer/cache,而实际配置了分离路径,会导致缓存完全失效——因为 Composer 会去挂载点找 files 和 repo 子目录,但它们并不存在。
- GitHub Actions 示例(关键两行):
- uses: actions/cache@v4with:path: |~/.composer/cache-files~/.composer/cache-repokey: composer-cache-${{ hashFiles('**/composer.lock') }} - Docker 构建中,
VOLUME必须声明两个路径:VOLUME ["/root/.composer/cache-files", "/root/.composer/cache-repo"] - 漏掉任一路径,对应部分缓存将落在容器临时文件系统,构建结束后即丢失
实际操作中最容易被忽略的,是 cache-repo 目录在首次使用分离配置时并不会自动创建——它只在第一次 composer update 后才生成。如果备份脚本在初始化阶段就执行,可能误以为目录为空而跳过,结果恢复时缺失元数据索引。


















