使用Composer的开发/生产开关时如何正确部署?

Sli*_*liq 159 php deployment composer-php

Composer可以选择仅在开发时加载多个依赖项,因此这些工具不会安装在生产环境中(在实时服务器上).对于仅在开发中有意义的脚本(如测试,伪数据工具,调试器等),这(理论上)非常方便.

要做的就是require-dev使用dev中需要的工具添加一个额外的块:

"require-dev": {
    "codeception/codeception": "1.6.0.3"
}
Run Code Online (Sandbox Code Playgroud)

然后(理论上)通过加载这些依赖

composer install --dev
Run Code Online (Sandbox Code Playgroud)

问题与疑问:

Composer已经改变了2013年的行为,install并且updaterequire-dev默认情况下安装了依赖项(!),随意创建一个带有require-dev块的composer.json 并执行composer install重现.

最受欢迎的部署方式是推动作曲家.锁定(保存当前的作曲家设置),然后composer install在生产服务器上执行,这也将安装开发的东西.

安装-dev依赖项的情况下部署此方法的正确方法是什么?

注意:我正在尝试创建一个规范的Q/A,以澄清奇怪的Composer部署.随意编辑这个问题.

Jas*_*wer 287

为什么

恕我直言,如今,Composer将--dev默认使用该标志(在安装更新时).Composer主要在场景中运行,这是期望的行为:

基本的Composer工作流程如下:

  • 启动一个新项目:composer.phar install --devjson和lock文件被提交给VCS.
  • 其他开发人员开始从事该项目的工作:结账VCS和composer.phar install --dev.
  • 开发人员添加依赖项:如果您想要包中的包(并提交)composer.phar require <package>,请添加.--devrequire-dev
  • 其他人继续:(结账和)composer.phar install --dev.
  • 开发人员需要更新版本的依赖项:( composer.phar update --dev <package>和提交).
  • 其他人继续:(结账和)composer.phar install --dev.
  • 项目部署: composer.phar install --no-dev

正如您所看到的那样,--dev标志比--no-dev标志更多地使用(特别是当项目开发人员数量增加时).

生产部署

在没有安装"dev"依赖项的情况下部署它的正确方法是什么?

那么,composer.jsoncomposer.lock文件应该提交给VCS.不要省略,composer.lock因为它包含应该使用的包版本的重要信息.

执行生产部署时,您可以将--no-dev标志传递给Composer:

composer.phar install --no-dev
Run Code Online (Sandbox Code Playgroud)

composer.lock文件可能包含有关dev-packages的信息.这没关系.该--no-dev标志将确保未安装这些开发包.

当我说"生产部署"时,我指的是旨在用于生产的部署.我不是在讨论是composer.phar install应该在生产服务器上还是在可以查看内容的登台服务器上完成的.这不是这个答案的范围.我只是指出如何composer.phar install不安装"dev"依赖项.

无关

--optimize-autoloader生产时也可能需要该标志(它会生成一个类映射,可以加速应用程序中的自动加载):

composer.phar install --no-dev --optimize-autoloader
Run Code Online (Sandbox Code Playgroud)

或者在完成自动部署时:

composer.phar install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --no-suggest --optimize-autoloader
Run Code Online (Sandbox Code Playgroud)

  • 我同意大多数有一个例外的说法."composer install --no-dev"应仅在暂存环境中执行,并且该环境应视为不可变.我不想直接在我的生产服务器上下载任何依赖项,也不需要进行预览/暂存.这只是一个额外的谨慎. (5认同)
  • 实际上我认为默认应该是危险性较小的选项.制作--dev默认值并意外地在生产中进行作曲家安装可能是致命的. (5认同)
  • @Scalable:虽然我同意你的意见(并且Sven在他的回答中很好地介绍了这一点),但这不是我答案的范围,而不是我对"生产部署"的意思.我添加了一个段落来清楚说明. (3认同)
  • `--optimize-autoloader`中的好点.想想也是`--classmap-authoritative` - 从文档这里https://getcomposer.org/doc/03-cli.md你可以看到这一点:"从类映射自动加载类只是含蓄地使--optimize-自动加载."所以你可以使用,如果你知道"在那里"的类,这可能会在你的prod环境中发生,除非你动态生成类. (3认同)
  • 很好的答案,我建议直接在`composer.json`中添加`optimize-autoloader`:`{"config":{"optimize-autoloader":true}}` (3认同)

Sve*_*ven 70

实际上,我强烈建议AGAINST在生产服务器上安装依赖项.

我的建议是检查部署机器上的代码,根据需要安装依赖项(这包括在代码进入生产时不安装dev依赖项),然后将所有文件移动到目标机器.

为什么?

  • 在共享主机上,您可能无法访问命令行
  • 即使你这样做,PHP在命令,内存或网络访问方面也可能受到限制
  • 存储库CLI工具(Git,Svn)可能不会被安装,如果你的锁文件记录了一个依赖项来检查某个提交而不是将该提交下载为ZIP(你使用了--prefer-source,或者Composer没有其他方法可以获得该版本)
  • 如果您的生产机器更像是一个小型测试服务器(想想Amazon EC2微型实例),则可能没有足够的内存来执行 composer install
  • 虽然作曲家试图不破坏事物,你觉得如何以部分破碎的制作网站结束,因为在Composers安装阶段无法加载一些随机依赖

简而言之:在您可以控制的环境中使用Composer.您的开发机器确实符合条件,因为您已经拥有运行Composer所需的所有东西.

在不安装-dev依赖项的情况下部署此方法的正确方法是什么?

要使用的命令是

composer install --no-dev
Run Code Online (Sandbox Code Playgroud)

这将适用于任何环境,无论是生产服务器本身,还是部署机器,或者应该进行最后检查以查找是否有任何开发需求被错误地用于真实软件的开发机器.

该命令不会安装或主动卸载composer.lock文件中声明的dev要求.

如果您不介意在生产服务器上部署开发软件组件,则运行composer install将执行相同的工作,但只是增加移动的字节数,并创建更大的自动加载器声明.

  • 我建议的工作流程不包括通过GIT将代码推送到生产服务器.事实上,我建议不要这样做,因为这样做会迫使你在生产服务器上安装Composer依赖项,这会带来任何数量的问题.如果希望部署顺利运行,则必须先组合运行应用程序所需的所有代码,然后再销毁当前版本并替换它.不喜欢FTP?通过SSH进行RSync,然后通过翻转符号链接来切换版本.但是如果你愿意的话,你也可以推送,结帐和编辑器安装. (16认同)
  • 有趣的工作流程,但有一个很大的问题:存储库不应该包含供应商文件夹/内容本身(Composer页面上的官方声明),因此它们永远不会在基于git的部署中直接推送到生产中(这是一个普通标准afaik,如果我错了,请纠正我.所以基本上上面的解决方案只适用于"老派"FTP部署!请让我们进一步讨论...... (14认同)
  • 我同意这个答案的100%.Composer不应安装在部署服务器上,也不应安装在git上.持续部署/集成服务器完全应该管理源和依赖项提取:git pull> composer install> deploy (3认同)
  • @Panique:我刚看到你的评论的一部分,我必须回答:"在基于git的部署中推动生产(这是一个常见的标准afaik,如果我错了就纠正我)" - 不,这个不是通用标准.这只是一种方法. (2认同)
  • 我所在的团队已将其纳入他们的工作流程并取得了巨大成功。我们有一台构建机器(当然是 Jenkins),它:1)从 SC 检出 2)运行 composer install/update 3)运行单元测试 4)删除开发依赖 5)生成一个 phar 文件(`app-1.34.phar`等等)。有一个单独的机制可以通知并决定何时获取该文件、将其传输到何处以及如何处理它。有些团队选择在 phar 放在服务器上后将其解压缩,而有些团队则按原样运行。这让我们对部署的稳定性和可重复性充满信心。 (2认同)

dav*_*010 5

现在require-dev默认启用,对于本地开发,您可以执行composer install并且composer update不使用该--dev选项。

当您想要部署到生产环境时,您需要确保composer.lock没有任何来自require-dev.

你可以这样做

composer update --no-dev
Run Code Online (Sandbox Code Playgroud)

使用本地测试后,--no-dev您可以将所有内容部署到生产环境并基于composer.lock. 您在--no-dev这里再次需要该选项,否则作曲家会说“锁定文件不包含 require-dev 信息”

composer install --no-dev
Run Code Online (Sandbox Code Playgroud)

注意:小心任何有可能在开发和生产之间引入差异的东西!我通常尽量避免使用 require-dev,因为包含开发工具并不是一个很大的开销。

  • 这在细节上实际上是不正确的。无需检查 `composer.lock` 的开发依赖项。您只需运行`composer install --no-dev`,您将只安装常规依赖项——事实上,Composer 还将在此步骤中删除所有开发依赖项。 (2认同)