CircleCI中必须只缓存~/.composer/cache路径,因其仅存dist包和元数据,与环境解耦;缓存vendor/会导致autoload错乱,缓存整个~/.composer/则泄露配置和凭证。

CircleCI里缓存~/.composer/cache到底该挂哪一级路径
必须只缓存 ~/.composer/cache,不能缓存 vendor/,更不能缓存整个 ~/.composer/。前者导致 autoload 错乱,后者会把用户配置、凭证等不该共享的内容也卷入缓存,引发权限或镜像失效问题。
CircleCI 的 save_cache 和 restore_cache 只认路径,不自动识别 Composer 缓存结构。所以你要显式指定:
-
paths: ["~/.composer/cache"]—— 这是唯一安全且有效的路径 -
key必须包含${{ checksum "composer.lock" }},否则 lock 文件一变,缓存就失效 - 别写成
~/.composer/cache/files或~/.composer/cache/repo—— Composer 2.2+ 会动态调整子目录结构,硬写死路径容易漏掉校验文件
为什么 composer install --no-dev -o 在 CircleCI 里必须加 --classmap-authoritative
不加 --classmap-authoritative,即使开了 --optimize-autoloader,Composer 仍会在运行时 fallback 到 PSR-4/PSR-0 扫描,这在 CI 构建后打包镜像、再部署到不同环境时,极易因文件系统大小写或符号链接行为差异触发 Class not found。
这个参数强制 autoloader 只信任 classmap,彻底关闭动态扫描。它和 --optimize-autoloader 是配套组合,不是可选项:
-
composer install --no-dev -o --classmap-authoritative是生产级 CI 构建的最小安全集 - 漏掉
--classmap-authoritative,-o效果打折;漏掉-o,--classmap-authoritative无法生成 classmap - 某些 Laravel 项目还会额外需要
--apcu-autoloader,但前提是 PHP 已加载apcu.so且未设apc.enable_cli=1
怎么验证 CircleCI 中 Composer 镜像真生效了
执行 composer config -g repo.packagist 输出为空、null 或仍是 https://packagist.org,说明镜像没落到实际运行命令的用户家目录下——这是 CircleCI 里最常踩的坑。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
原因通常是:sudo composer config -g 写进了 root 的 ~/.composer/config.json,而 CircleCI 默认以 circleci 用户运行 job,读不到 root 的配置。
正确做法是:
- 在 job 的
steps里,用普通用户身份执行composer config -g repo.packagist https://mirrors.aliyun.com/composer/ - 紧接着跑
composer install -vvv | head -n 20,确认日志里出现GET https://mirrors.aliyun.com/composer/p2/ - 别依赖
COMPOSER_REPO_PACKAGIST环境变量——它只影响单次命令,不写入全局 config,缓存复用时会失效
cache key 里除了 composer.lock 还要带什么
只靠 ${{ checksum "composer.lock" }} 不够。Composer 缓存内容受 PHP 版本、扩展开关(如 ext-zip)、甚至 Composer 自身版本影响。同一份 lock 文件,在 PHP 8.1 和 8.2 下生成的 classmap 不兼容。
所以 key 必须拼接多维标识:
composer-cache-v1-{{ checksum "composer.lock" }}-{{ .Environment.PHP_VERSION }}-{{ arch }}- CircleCI 提供
.Environment.PHP_VERSION,但没内置arch,可用run: echo "arch=$(uname -m)" >> $BASH_ENV注入 - 如果用了自定义
cache-dir(比如挂到/tmp/composer-cache),key 里还得体现该路径哈希,否则多个 job 并行时可能相互污染
缓存命中的安静,往往掩盖了跨版本复用的风险;真正出问题,是在部署后第一秒 autoload 失败。

















