如何在GitLab CI/CD中配置Composer的缓存? (CI/CD集成)

13次阅读

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

如何在GitLab CI/CD中配置Composer的缓存? (CI/CD集成)

为什么 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-gdext-mbstring)时
  • CI 镜像中 PHP 版本应显式指定(如 image: php:8.2-cli),不要依赖默认标签

缓存本身不难配,难的是让缓存「稳定命中」且「不引入隐性故障」——composer.lock 的完整性、key 的唯一性、PHP 环境的一致性,三者缺一不可。

text=ZqhQzanResources