Ansible部署PHP依赖时,composer install必须在Composer已安装、PHP环境就绪、composer.lock存在并同步的前提下执行;否则会失败或装错版本。

Ansible 部署 PHP 依赖环境时,composer install 必须在 Composer 已安装、PHP 环境就绪、且 composer.lock 文件存在并已同步的前提下执行;否则会失败或装错版本。
Ansible 中安装 Composer 的两种可靠方式
直接用 get_url + shell 安装最可控,适合对目标主机权限有限或需跳过包管理器的场景;而使用 community.general.composer 模块更语义化,但要求目标主机已预装 Composer。
- 用
get_url下载 installer 后用php执行安装:必须指定mode: '0755'并确保/usr/local/bin在PATH中,否则composer命令不可用 -
community.general.composer模块不负责安装 Composer 本身,只调用已存在的composer二进制 —— 若未提前安装,任务会报错"composer command not found" - 推荐组合:先用
geerlingguy.composer角色统一安装(支持composer_version变量锁定版本),再用community.general.composer执行项目级操作
运行 composer install 时必须检查的三个前提
Ansible 执行失败常不是因为命令写错,而是环境没准备好。这三个条件缺一不可:
-
working_dir(如/var/www/project)必须存在,且该路径下已有composer.json和composer.lock——composer install不会生成composer.lock,只读取它 - PHP 进程需启用
openssl、zlib、json扩展,否则安装过程会在下载包或解压时静默失败(日志里只显示"failed to open stream") - 目标用户(如
www-data或deploy)必须对working_dir有读写权限;若用become: yes切换用户,注意HOME环境变量可能丢失,导致 Composer 缓存路径异常
--no-dev 和 --optimize-autoloader 在生产部署中的实际影响
这两个参数不是“可选优化”,而是生产环境的硬性安全与性能边界。
-
--no-dev会跳过require-dev区块里的包(如phpunit、mockery),避免把测试工具暴露在生产服务器上 —— 曾有项目因漏加此参数,导致vendor/bin/phpunit被扫描出远程代码执行漏洞 -
--optimize-autoloader会生成vendor/composer/autoload_classmap.php,将类名到文件路径的映射固化为数组,减少file_exists()调用;但前提是项目中没有动态类加载逻辑(如基于文件名反射),否则会漏加载 - 不要在 Ansible 任务中混用
--dev和--no-dev;composer install默认行为是按composer.lock安装全部依赖,只有显式加--no-dev才跳过开发依赖
为什么 post-install-cmd 脚本在 Ansible 部署里大概率不执行
Ansible 调用的是系统级 composer 命令,不是通过 PHP CLI 加载项目 autoloader 后触发的钩子,所以 composer.json 里的 scripts 字段默认不生效。
- 除非你在 Ansible 任务中显式调用
composer run-script post-install-cmd,否则钩子不会运行 - 即使运行了,也要注意脚本执行用户和工作目录:Ansible 默认以
root运行,而post-install-cmd脚本里若含chmod或chown,很可能因权限过高或路径错误失败 - 真正可靠的自动化动作(如复制
.env、生成缓存)应该写在 Ansible task 里,而不是依赖 Composer 钩子 —— 钩子更适合本地开发辅助,而非部署一致性保障
最容易被忽略的是 composer.lock 文件的 Git 提交状态和 PHP 扩展可用性检查 —— 它们不出现在任何 playbook 日志里,却直接决定部署是否真的“成功”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











