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

时间:2014-02-12 07:35:39

标签: php deployment composer-php

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

可行的方法是使用开发中所需的工具添加额外的require-dev块:

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

然后(理论上)通过

加载这些依赖项
composer install --dev

问题&问题:

Composer在2013年大幅改变了installupdate的行为,require-dev - 现在默认安装依赖项(!),随意创建一个composer.json require-dev阻止并执行composer install来重现。

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

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

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

5 个答案:

答案 0 :(得分:259)

<强>为什么

现在有一个很好的理由,为什么Composer默认会使用--dev标志(在安装更新时)。 Composer主要在场景中运行,这是期望的行为:

基本的Composer工作流程如下:

  • 启动一个新项目:composer.phar install --dev,json和锁定文件将提交给VCS。
  • 其他开发人员开始处理该项目:签出VCS和composer.phar install --dev
  • 开发人员添加依赖项:composer.phar require <package>,如果您想要--dev部分中的包(并提交),请添加require-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

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

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

<强> Offtopic

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

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

自动部署完成后:

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

答案 1 :(得分:65)

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

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

为什么呢?

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

长话短说:在您可以控制的环境中使用Composer。您的开发机器确实符合条件,因为您已经掌握了运行Composer所需的所有内容。

  

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

要使用的命令是

composer install --no-dev

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

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

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

答案 2 :(得分:2)

默认情况下启用require-dev,对于本地开发,您可以composer installcomposer update执行--dev选项。

如果要部署到生产环境,则需要确保composer.lock没有来自require-dev的任何软件包。

您可以使用

执行此操作
composer update --no-dev

使用--no-dev进行本地测试后,您可以根据composer.lock将所有内容部署到生产和安装。您需要在此再次使用--no-dev选项,否则编写者会说“锁定文件不包含require-dev信息”

composer install --no-dev

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

答案 3 :(得分:2)

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

在你的git存储库中添加composer.lock文件,确保你在发布时使用 composer.phar install --no-dev ,但在你的dev机器中你可以使用任何composer命令而不用担心,这将不会生产,生产将依赖于锁文件。

在服务器上检查此特定版本或标签,并在更换应用程序之前运行所有测试,如果测试通过则继续部署。

如果测试依赖于dev依赖关系,因为作曲家没有测试范围依赖关系,可以使用dev依赖关系运行一个不太优雅的解决方案( composer.phar install ),删除供应商库,再次运行 composer.phar install --no-dev ,这将使用缓存的依赖项,因此更快。但如果您了解其他构建工具中的范围概念,则这是一个黑客攻击

自动化并忘记休息,去喝啤酒: - )

PS。:正如在下面的@Sven评论中那样,不要检查composer.lock文件是个好主意,因为这会使作曲家安装工作为作曲家更新。

您可以使用http://deployer.org/进行自动化,这是一个简单的工具。

答案 4 :(得分:1)

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

HTTP cookie导致我的系统选择新的供应商autoload.php,并且在测试之后我在它们之间进行完全原子/即时切换以禁用所有未来请求的旧供应商目录,然后我删除以前的目录几天后。

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

尽管有其他答案建议反对它,我个人在服务器上运行composer install,因为这比我的暂存区域(我的笔记本电脑上的VM)的rsync更快。

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