CI/CD中必须用composer install而非update,因update会修改composer.lock导致构建不可复现;install则严格按lock文件安装,确保环境一致性,并需加--no-dev、--no-interaction、--optimize-autoloader参数。
composer install,禁用
composer update
CI/CD 流水线里运行 composer update 是高风险操作,它会主动修改 composer.lock 并拉取最新兼容版本,导致构建结果不可复现。生产环境部署必须和本地开发、测试环境使用完全一致的依赖版本,而只有 composer install 能保证这一点——它只按 composer.lock 安装,不读取 composer.json 的版本约束做决策。
composer install 在 CI 中的正确用法默认行为已足够安全,但需显式控制几个关键参数:
--no-dev:CI 构建生产镜像或部署包时,不应安装 require-dev 里的包(如 PHPUnit、PHPStan),避免体积膨胀与潜在冲突--no-interaction 和 --optimize-autoloader:跳过交互提示,生成优化后的类映射,提升运行时性能composer.lock 已提交到 Git:这是 install 可复现的前提;若缺失,install 会退化为 update 行为并报错(除非加 --ignore-platform-reqs,但这是掩盖问题)composer install --no-dev --no-interaction --optimize-autoloader
composer update?仅限开发者本地环境,且需满足两个条件:
composer.lock 文件——CI 后续所有构建都基于这个新锁文件CI 流水线中出现 update 命令,基本意味着流程设计错误:要么是误把开发流程混入部署阶段,要么是试图用 CI 自动“保版本最新”,这违背了可复现性原则。
以下迹象说明 CI 中误用了 update 或锁文件管理失控:
Writing lock file 或 Generating autoload files 之后紧接着有大量 Installing ... 版本号变动monolog/monolog 版本不一致composer.lock 文件未被 Git 跟踪,或被 .gitignore 忽略composer update --with-dependencies 用于“确保安全”,实则制造不可控依赖漂移锁文件不是“可选附件”,它是 PHP 项目在 CI/CD 中实现确定性构建的契约。漏掉它,或者绕过它,等于放弃对依赖树的控制权。
# php
# 报错
# 可选
# 不应
# 镜像
# 它是
# 两次
# 什么时候
# 几个
# 这是
# require
# composer
# json
# git
# js
# 而非