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

Composer可以select仅在开发时加载多个依赖项,因此这些工具不会在生产环境中(在活动服务器上)安装。 这在理论上是非常方便的,只有在testing,假数据工具,debugging器等开发中才有意义的脚本。

要走的路是在开发中添加一个额外的require-dev块和你需要的工具:

 "require-dev": { "codeception/codeception": "1.6.0.3" } 

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

 composer install --dev 

问题和问题:

Composer已经在2013年大幅改变了installupdate的行为,现在默认安装require-dev -dependencies(!),随便用require-dev块创build一个composer.json并执行一个composer install来重现。

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

什么是正确的方式来部署这个没有安装-dev依赖关系?

注意:我试图在这里创build一个规范的Q / A来澄清怪异的Composer部署。 随意编辑这个问题。

为什么

恕我直言,一个很好的理由,为什么composer php将默认使用--dev标志(在安装更新)如今。 composer php主要是在场景中,这是所需的行为:

基本的Composer工作stream程如下:

  • 一个新的项目开始: composer.phar install --dev ,json和locking文件被提交给VCS。
  • 其他开发人员开始在项目上工作:签出VCS和composer.phar install --dev
  • 开发人员添加依赖关系: composer.phar require <package> ,如果require-dev部分(和提交)中的包,请添加--dev
  • 其他人去:(结帐和) composer.phar install --dev
  • 开发人员需要更新版本的依赖项: composer.phar update --dev <package> (和commit)。
  • 其他人去:(结帐和) composer.phar install --dev
  • 项目部署: composer.phar install --no-dev

正如你所看到的,– --dev标志被使用的远远超过了--no-dev标志,特别是在项目开发人员数量增长的时候。

生产部署

什么是正确的方式来部署这个没有安装“开发”的依赖关系?

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

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

 composer.phar install --no-dev 

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

当我说“生产部署”时,我的意思是一个旨在用于生产的部署。 我不争论是否应该在生产服务器上执行composer.phar install ,或者在可以检查事物的登台服务器上执行。 这不是这个答案的范围。 我只是指出如何在不安装“dev”依赖的情况下进行composer.phar install

无关

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

 composer.phar install --no-dev --optimize-autoloader 

或者当自动部署完成时:

 composer.phar install --no-ansi --no-dev --no-interaction --no-progress --no-scripts --optimize-autoloader 

实际上,我强烈build议不要在生产服务器上安装依赖项。

我的build议是签出部署机器上的代码,根据需要安装依赖关系(如果代码进入生产,则不包括安装开发依赖关系),然后将所有文件移至目标机器。

为什么?

  • 在共享主机上,您可能无法进入命令行
  • 即使你这样做,PHP也可能在命令,内存或networking访问方面受到限制
  • 存储库CLI工具(Git,Svn)可能不会被安装,如果你的locking文件logging了一个依赖项来检出某个提交,而不是下载那个提交为ZIP(你使用的是–prefer-source,或者是Composer有没有其他的方式来获得该版本)
  • 如果您的生产机器更像是一个小型的testing服务器(想想Amazon EC2微型实例),则可能安装的内存可能不足以执行composer install
  • 而composer php不会破坏的东西,你觉得以部分破碎的生产网站结束,因为在composer php安装阶段不能加载一些随机依赖

长话短说:在您可以控制的环境中使用Composer。 您的开发计算机确实符合要求,因为您已经拥有操作Composer所需的所有function。

什么是正确的方式来部署这个没有安装-dev依赖关系?

要使用的命令是

 composer install --no-dev 

这可以在任何环境下工作,不pipe是生产服务器本身,还是部署机器,或者应该做最后一次检查的开发机器,以查找是否有任何开发需求被错误地用于真正的软件。

该命令不会安装或主动卸载composer.lock文件中声明的开发需求。

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

我认为是更好的自动化过程:

在你的git仓库中添加composer.lock文件,确保在你释放的时候使用composer.phar install –no-dev ,但是在你开发的时候,你可以使用任何composer命令,而不用担心,生产将依赖于锁文件。

在服务器上签出这个特定的版本或标签,并在更换应用程序之前运行所有testing,如果testing通过,则继续部署。

如果testing依赖于开发依赖关系,由于composer php没有testing范围依赖关系,可以使用开发依赖项( composer.phar install )运行testing并不是太优雅的解决scheme,可以删除供应商库,运行composer.phar –再次安装–no-dev ,这将使用caching的依赖关系,所以速度更快。 但是,如果您知道其他构build工具中的范围概念,那么这是一个黑客攻击

自动化,忘记其余的,去喝一杯啤酒:-)

PS:就像在@Sven注释下面,不检查composer.lock文件是不是一个好主意,因为这会使composer php安装工作作为composer php更新。

你可以用http://deployer.org/做这个自动化,它是一个简单的工具。;

现在require-dev默认启用require-dev ,对于本地开发,你可以在不使用--dev选项的情况下进行composer installcomposer update

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

你可以这样做

 composer update --no-dev 

使用--no-dev在本地进行testing后,您可以将所有内容都部署到基于composer.lock生产和安装中。 你需要在这里再次select--no-dev选项,否则作曲者会说“locking文件不包含require-dev信息”

 composer install --no-dev 

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

在生产服务器上,我将vendor重命名为vendor vendor-<datetime> ,在部署过程中将有两个供应商目录。

一个HTTP cookie导致我的系统select新的供应商autoload.php ,在testing之后,我做了一个完全primefaces/即时切换,以禁止所有未来的请求旧的供应商目录,然后我删除以前的dir几天后。

这避免了我在apache / php中使用的文件系统caching引起的任何问题,也允许任何活动的PHP代码继续使用以前的供应商目录。


尽pipe有其他的解决方法,但是我个人在服务器上运行composer install ,因为它比我的临时区域(我的笔记本电脑上的虚拟机)的rsync速度更快。

我使用--no-dev --no-scripts --optimize-autoloader 。 您应该阅读每个文档,以检查这是否适合您的环境。