缓存本身不加速,真正决定快慢的是composer install;必须同时配置--prefer-dist和--no-interaction,否则缓存几乎无效,因为~/.composer/cache存ZIP包,命中可省80%+网络I/O,而vendor缓存收益次之且易因环境差异失效。

缓存本身不加速,composer install 才真正决定快慢;只配 actions/cache 却漏掉 --prefer-dist 和 --no-interaction,缓存几乎无效。
为什么缓存 ~/.composer/cache 比缓存 vendor 更关键
Composer 的 ~/.composer/cache 存的是已下载的 ZIP 包(dist),而 vendor/ 是解压后的产物。只要 dist 缓存命中,composer install --prefer-dist 就跳过网络下载——这是提速主因;vendor 缓存只是“省了解压+自动加载生成”,收益次之。
-
~/.composer/cache命中 = 省掉 80%+ 的网络 I/O 时间(尤其国内) - vendor 缓存仅在 lock 未变、且 PHP 版本/扩展兼容时才安全复用
- CI 中 vendor 缓存易因
COMPOSER_HOME或平台差异失效,不如 dist 缓存稳定 - 必须提前执行
composer config --global cache-dir ~/.composer/cache,否则缓存路径不一致
cache key 必须用 hashFiles('**/composer.lock'),不能只写 'composer.lock'
GitHub Actions 的 hashFiles() 是 glob 函数,**/composer.lock 能覆盖子目录(如 packages/foo/composer.lock),而单写 composer.lock 只匹配根目录。多包 monorepo 项目一旦漏掉 **/,缓存 key 永远不变,导致旧依赖被错误复用。
- 正确写法:
${{ hashFiles('**/composer.lock') }} - 错误写法:
${{ hashFiles('composer.lock') }}(忽略子模块锁文件) - 若项目含多个 lock 文件,key 应包含所有路径:
${{ hashFiles('**/composer.lock', '**/packages/*/composer.lock') }} - 避免用
matrix.php-version作为 key 主干——PHP 小版本升级(如 8.2.1 → 8.2.2)不该触发全量重装
镜像源配置必须全局生效,且优先级高于 repo.packagist
执行 composer config repo.packagist composer https://mirrors.aliyun.com/composer/ 只改当前项目的 composer.json,CI 中每次 checkout 都是干净环境,该配置无效。必须用 --global 写入用户级配置,或在 CI step 中显式设置。
- 推荐做法:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 镜像源地址必须以
composer协议开头(不是https),否则 Composer 2.9+ 会报错Invalid repository type "https" - 腾讯云镜像同样有效:
https://mirrors.cloud.tencent.com/composer/ - 不要在
composer.json里硬编码镜像——它会被composer update覆盖,且污染开发者本地环境
Docker 构建中 --mount=type=cache 是比 actions/cache 更稳的方案
GitHub Actions 的 actions/cache 依赖网络上传/下载,大缓存(>500MB)可能超时或校验失败;Docker BuildKit 的 --mount=type=cache 直接在构建节点本地挂载,无传输开销,且自动处理并发写冲突。
- Dockerfile 中写法:
RUN --mount=type=cache,target=/root/.composer/cache composer install --no-dev --prefer-dist --no-interaction - 必须确保 base image 用户是
root(如php:8.3-cli),否则/root/.composer/cache不可写 - 非 root 用户需改 target 路径并 chown,例如:
--mount=type=cache,target=/home/www/.composer/cache,uid=33,gid=33 - 该方式天然规避了 GitHub Actions 缓存 restore-keys 的复杂逻辑,适合高频构建场景
最常被忽略的点:所有缓存提速的前提是 lock 文件真实反映依赖状态。如果开发中随意 composer update 却不提交 composer.lock,或者 CI 使用 --ignore-platform-reqs 绕过 PHP 版本检查,缓存再快也装不出正确依赖。


















