根本原因是CI中~/.composer/cache未持久化且未显式配置COMPOSER_CACHE_DIR,导致每次构建都丢失缓存;即使缓存vendor/,若composer.lock变更或未提交,install会退化为update行为,强制重下包。

CI中composer install为什么总在重下包
根本原因不是命令写错了,而是缓存路径没被真正复用。默认情况下 Composer 把包存在 ~/.composer/cache,但 CI runner 每次都是新容器,这个目录一重启就丢;即使你缓存了 vendor/,只要 composer.lock 文件内容变了、或没提交、或被 .gitignore 拦截,composer install 就会退化成 update 行为,重新解析依赖并下载——这时连 --prefer-dist 都救不了。
必须显式配置 COMPOSER_CACHE_DIR 并挂载共享路径
不能依赖默认路径,必须把缓存目录指向一个 CI 平台能跨 job 持久化的路径,比如 /tmp/composer-cache 或 .composer/cache(相对路径更易缓存)。同时要确保该路径被平台缓存机制覆盖:
- GitHub Actions:用
actions/cache@v3缓存.composer/cache,key 基于composer.lock的 SHA256 - GitLab CI:在
cache:下声明paths: - .composer/cache/,key 推荐用files: - composer.json - composer.lock - 自建 runner:需手动挂载宿主机目录到容器内
/tmp/composer-cache,并设环境变量COMPOSER_CACHE_DIR=/tmp/composer-cache
漏掉其中任意一环,缓存就形同虚设。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
Docker 构建时 vendor 层失效的常见陷阱
Docker 镜像分层缓存对 Composer 极其敏感,最常踩的坑是 COPY . /app 放太早:
- 错误写法:
COPY . /app && RUN composer install --no-dev --prefer-dist→ 每次代码变更都会让整个依赖安装层失效 - 正确顺序:先
COPY composer.json composer.lock ./,再RUN composer install --no-dev --prefer-dist --no-interaction,最后COPY . . - Alpine 镜像额外注意:
apk add curl openssl必须在composer install前装好,否则会静默卡住,不报错也不继续 - 别在
RUN中用composer create-project或require—— 它们绕过composer.lock,破坏可重现性
调试时怎么确认是否真走了缓存
别只看耗时,要看日志输出里有没有关键线索:
- 出现
Downloading xxx→ 正在重下,缓存未命中或被绕过 - 出现
Installing xxx from dist→ 走的是压缩包(本地缓存或远程 CDN),正常 - 出现
Cloning xxx或Checking out xxx→ 正在走 Git clone,说明用了 VCS 源且没走 dist,或者--prefer-dist没生效 - 加
-v或-vvv才能看到这些行;--no-cache会强制触发Downloading,仅用于排查,不可长期启用
真正难处理的是 VCS 镜像缓存(~/.composer/cache/vcs/)——它不随 --no-cache 清除,得手动删或设 COMPOSER_CACHE_DIR=/dev/null 才能彻底绕过。

















