只缓存 vendor/ 会失效,因为未缓存 ~/.composer/cache 导致 composer install 无法复用 zip 包,必须重下重解;必须同时缓存 vendor/ 和 ~/.composer/cache,并配 --no-interaction --prefer-dist --optimize-autoloader 才能真正加速。

为什么只缓存 vendor/ 会失效
CI 构建中常见现象:缓存了 vendor/,但 composer install 仍要花 2 分钟以上,日志里满屏 Downloading xxx.zip。根本原因不是 vendor 没命中的问题,而是 COMPOSER_CACHE_DIR(默认 ~/.composer/cache)每次都被清空——Composer 安装前必须从这个目录解包、校验哈希、写临时文件;没它,--prefer-dist 就形同虚设,所有 ZIP 包重下重解。
必须同时缓存的两个路径
只缓存其中一个,等于没缓存。正确做法是双路径声明:
-
vendor/(注意排除vendor/bin/符号链接和生成类如vendor/autoload.php的临时内容) -
~/.composer/cache(推荐显式设为$HOME/.composer-cache-$PHP_VERSION,避免多 PHP 版本混用)
GitLab CI 示例:
cache:
key: files: [composer.lock]
prefix: "${CI_JOB_NAME}-php-${PHP_VERSION}"
paths:
- vendor/
- ~/.composer-cache-$PHP_VERSION
GitHub Actions 示例(actions/cache@v4):
with:
path: |
vendor
~/.composer/cache
key: ${{ runner.os }}-php-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
composer install 必须带的三个参数
缺一不可,否则缓存基本白搭:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
--no-interaction:跳过交互提示,CI 必备 -
--prefer-dist:强制走 ZIP 包安装(比 git clone 快 3–5 倍),且只有它才能命中~/.composer/cache中的 dist 缓存;漏掉它,哪怕 cache-dir 存在,也会 fallback 到 source -
--optimize-autoloader:生成扁平化autoload_classmap.php,跳过运行时file_exists()探测,加载类快 20%+,对测试启动时间敏感
额外建议加 --no-dev:CI 环境通常不需要 dev 依赖,漏掉它会让安装时间多出 30%–60%,尤其含 phpunit 或 phpstan 的项目。
缓存键(key)必须包含哪些变量
只用 hashFiles('**/composer.lock') 是最常见失误。以下变量缺一不可,否则缓存会静默错配:
- 操作系统(
${{ runner.os }}或$CI_JOB_NAME) - PHP 版本(
${{ matrix.php-version }}或$PHP_VERSION)——不同 minor 版本(8.2.12 → 8.2.15)可能导致 opcache 行为差异 - Composer 版本(
${{ steps.composer-version.outputs.version }})——2.2 和 2.5 插件加载机制不同,混用会污染缓存 -
composer.json哈希(hashFiles('composer.json'))——覆盖config.platform或scripts变动
restore-keys 不是可选项,是必填项。例如结尾加一个 -,让缓存能 fallback 到最近一次兼容版本(如 PHP 小版本升级、Composer 补丁更新)。
真正容易被忽略的是:缓存 ~/.composer/cache 后,必须确保 CI 环境里没有残留的旧源配置(比如私有镜像未生效或 PAT 凭据缺失),否则即使缓存命中,也会在 git clone 阶段卡住并报 could not read Username ——这种失败不报错,但会拖慢整个流程。










