Composer install 慢的根本原因是 GitLab CI 未缓存 ~/.composer/cache,导致每次重下依赖;必须缓存该路径并用 composer.lock SHA 和 PHP 版本构建唯一 key,配合 --prefer-dist 等参数确保命中与兼容。

为什么 Composer install 每次都慢?
根本原因是 GitLab CI 默认不保留 vendor/ 目录和 Composer 的全局缓存(~/.composer/cache),每次作业都从零下载依赖,耗时翻倍甚至更久。缓存不是可选项,而是必须项。
正确配置 Composer 缓存的两个关键路径
GitLab CI 不支持直接缓存 vendor/(因它含平台相关二进制、且与 composer.lock 严格耦合),应只缓存 Composer 自身的下载缓存和已安装包的归档(~/.composer/cache/files/)。同时需确保 COMPOSER_CACHE_DIR 显式指向该路径。
- 在
.gitlab-ci.yml中声明缓存路径:cache: key: "$CI_JOB_NAME" paths: - ~/.composer/cache/ - 在
before_script或作业中设置环境变量:export COMPOSER_CACHE_DIR="$HOME/.composer/cache"
- 务必使用
composer install --no-interaction --prefer-dist --optimize-autoloader:避免 dev 依赖干扰、强制走压缩包而非 Git 克隆、提升加载性能
缓存失效常见原因和应对
缓存没生效?大概率是 key 设计不合理或 lock 文件未被纳入缓存决策。GitLab 的 cache.key 不会自动感知 composer.lock 变更。
- 推荐用
cache.key基于composer.lock的 SHA:cache: key: ${CI_COMMIT_REF_SLUG}-composer-${CI_PROJECT_ID}-${CI_PIPELINE_ID} # 更稳妥做法:用 checksum 替代 pipeline ID(需先计算) # key: "composer-$(sha256sum composer.lock | cut -d' ' -f1)" - 确保
composer.lock存在且已提交——没有 lock 文件时,composer install会退化为update,彻底绕过缓存 - 私有包(如 GitLab 私有仓库)需提前配置
auth.json并设为 CI 变量(COMPOSER_AUTH),否则缓存会因认证失败中断
PHP 版本与缓存兼容性陷阱
Composer 缓存内容受 PHP 版本影响。若多个作业共用同一缓存但 PHP 版本不同(如 8.1 和 8.2),可能触发 opcache 冲突或扩展 ABI 不匹配,导致 vendor/ 安装后运行报错。
- 按 PHP 版本分隔缓存
key:key: "${CI_JOB_NAME}-php-${PHP_VERSION}-$(sha256sum composer.lock | cut -d' ' -f1)" - 避免跨版本复用缓存,尤其当项目含
ext-*扩展依赖(如ext-gd、ext-mbstring)时 - CI 镜像中 PHP 版本应显式指定(如
image: php:8.2-cli),不要依赖默认标签
缓存本身不难配,难的是让缓存「稳定命中」且「不引入隐性故障」——composer.lock 的完整性、key 的唯一性、PHP 环境的一致性,三者缺一不可。










