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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21721495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:24:20  来源:igfitidea点击:

How to deploy correctly when using Composer's develop / production switch?

phpdeploymentcomposer-php

提问by Sliq

Composer has the option to load several dependencies only while being in development, so the tools will not be installed in production (on the live server). This is (in theory) very handy for scripts that only make sense in development, like tests, fake-data-tools, debugger, etc.

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

The way to go is to add an additional require-devblock with the tools you need in dev:

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

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

and then (theoretically) load these dependencies via

然后(理论上)通过以下方式加载这些依赖项

composer install --dev

Problem & Question:

问题与疑问:

Composer has changed the behaviour of installand updatedramatically in 2013, require-dev-dependencies are now installed by default (!), feel free to create a composer.json with a require-devblock and perform an composer installto reproduce.

作曲家改变了行为installupdate显着,2013年,require-dev-dependencies现在默认安装(!),随意创建具有一个composer.jsonrequire-dev块和执行composer install重现。

As the most accepted way to deploy is to push the composer.lock(that holds your current composer setup) and then do an composer installon the production server, this will also install the development stuff.

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

What's the correct way to deploy this withoutinstalling the -dev dependencies ?

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

Note: I'm trying to create a canonical Q/A here to clarify the weird Composer deployment. Feel free to edit this question.

注意:我试图在这里创建一个规范的问答来澄清奇怪的 Composer 部署。随意编辑这个问题。

回答by Jasper N. Brouwer

Why

为什么

There is IMHO a good reason why Composer will use the --devflag by default (on install andupdate) nowadays. Composer is mostly run in scenario's where this is desired behavior:

恕我直言,现在 Composer 将在--dev默认情况下(在安装更新时)使用该标志是有充分理由的。Composer 主要在需要这种行为的场景中运行:

The basic Composer workflow is as follows:

基本的 Composer 工作流程如下:

  • A new project is started: composer.phar install --dev, json and lock files are commited to VCS.
  • Other developers start working on the project: checkout of VCS and composer.phar install --dev.
  • A developer adds dependancies: composer.phar require <package>, add --devif you want the package in the require-devsection (and commit).
  • Others go along: (checkout and) composer.phar install --dev.
  • A developer wants newer versions of dependencies: composer.phar update --dev <package>(and commit).
  • Others go along: (checkout and) composer.phar install --dev.
  • Project is deployed: composer.phar install --no-dev
  • 一个新的项目开始了:composer.phar install --dev,json 和 lock 文件被提交到 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

As you can see the --devflag is used (far) more than the --no-devflag, especially when the number of developers working on the project grows.

如您所见,该--dev标志的使用(远)比该--no-dev标志的使用更多,尤其是当从事该项目的开发人员数量增加时。

Production deploy

生产部署

What's the correct way to deploy this without installing the "dev" dependencies?

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

Well, the composer.jsonand composer.lockfile should be committed to VCS. Don't omit composer.lockbecause it contains important information on package-versions that should be used.

那么,composer.jsoncomposer.lock文件应致力于VCS。不要省略,composer.lock因为它包含有关应该使用的包版本的重要信息。

When performing a production deploy, you can pass the --no-devflag to Composer:

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

composer.phar install --no-dev

The composer.lockfile might contain information about dev-packages. This doesn't matter. The --no-devflag will make sure those dev-packages are not installed.

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

When I say "production deploy", I mean a deploy that's aimed at being used in production. I'm not arguing whether a composer.phar installshould be done on a production server, or on a staging server where things can be reviewed. That is not the scope of this answer. I'm merely pointing out how to composer.phar installwithout installing "dev" dependencies.

当我说“生产部署”时,我指的是旨在用于生产的部署。我不是在争论是composer.phar install应该在生产服务器上还是在可以事情的临时服务器上完成。这不是这个答案的范围。我只是指出如何composer.phar install不安装“开发”依赖项。

Offtopic

题外话

The --optimize-autoloaderflag might also be desirable on production (it generates a class-map which will speed up autoloading in your application):

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

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

Or when automated deployment is done:

或者当自动部署完成时:

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

If your codebase supports it, you could swap out --optimize-autoloaderfor --classmap-authoritative. More info here

如果你的代码库支持的话,你可以换出--optimize-autoloader--classmap-authoritative。更多信息在这里

回答by Sven

Actually, I would highly recommend AGAINST installing dependencies on the production server.

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

My recommendation is to checkout the code on a deployment machine, install dependencies as needed (this includes NOT installing dev dependencies if the code goes to production), and then move all the files to the target machine.

我的建议是在部署机器上签出代码,根据需要安装依赖项(这包括如果代码投入生产,则不安装开发依赖项),然后将所有文件移动到目标机器上。

Why?

为什么?

  • on shared hosting, you might not be able to get to a command line
  • even if you did, PHP might be restricted there in terms of commands, memory or network access
  • repository CLI tools (Git, Svn) are likely to not be installed, which would fail if your lock file has recorded a dependency to checkout a certain commit instead of downloading that commit as ZIP (you used --prefer-source, or Composer had no other way to get that version)
  • if your production machine is more like a small test server (think Amazon EC2 micro instance) there is probably not even enough memory installed to execute composer install
  • while composer tries to no break things, how do you feel about ending with a partially broken production website because some random dependency could not be loaded during Composers install phase
  • 在共享主机上,您可能无法访问命令行
  • 即使您这样做了,PHP 也可能在命令、内存或网络访问方面受到限制
  • 可能不会安装存储库 CLI 工具(Git、Svn),如果您的锁定文件记录了检出某个提交的依赖项,而不是将该提交下载为 ZIP(您使用 --prefer-source 或 Composer 已没有其他方法可以获得该版本)
  • 如果您的生产机器更像是一个小型测试服务器(想想 Amazon EC2 微型实例),则可能甚至没有安装足够的内存来执行 composer install
  • 虽然作曲家试图不破坏事物,但您如何看待以部分损坏的生产网站结束,因为在作曲家安装阶段无法加载某些随机依赖项

Long story short: Use Composer in an environment you can control. Your development machine does qualify because you already have all the things that are needed to operate Composer.

长话短说:在您可以控制的环境中使用 Composer。您的开发机器确实符合条件,因为您已经拥有操作 Composer 所需的所有东西。

What's the correct way to deploy this without installing the -dev dependencies?

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

The command to use is

要使用的命令是

composer install --no-dev

This will work in any environment, be it the production server itself, or a deployment machine, or the development machine that is supposed to do a last check to find whether any dev requirement is incorrectly used for the real software.

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

The command will not install, or actively uninstall, the dev requirements declared in the composer.lock file.

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

If you don't mind deploying development software components on a production server, running composer installwould do the same job, but simply increase the amount of bytes moved around, and also create a bigger autoloader declaration.

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

回答by dave1010

Now require-devis enabled by default, for local development you can do composer installand composer updatewithout the --devoption.

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

When you want to deploy to production, you'll need to make sure composer.lockdoesn't have any packages that came from require-dev.

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

You can do this with

你可以这样做

composer update --no-dev

Once you've tested locally with --no-devyou can deploy everything to production and install based on the composer.lock. You need the --no-devoption again here, otherwise composer will say "The lock file does not contain require-dev information".

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

composer install --no-dev

Note:Be careful with anything that has the potential to introduce differences between dev and production! I generally try to avoid require-dev wherever possible, as including dev tools isn't a big overhead.

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

回答by Giovanni Silva

I think is better automate the process:

我认为更好地自动化流程:

Add the composer.lock file in your git repository, make sure you use composer.phar install --no-devwhen you release, but in you dev machine you could use any composer command without concerns, this will no go to production, the production will base its dependencies in the lock file.

将 composer.lock 文件添加到您的 git 存储库中,确保您在发布时使用composer.phar install --no-dev,但是在您的开发机器中您可以毫无顾虑地使用任何 composer 命令,这将不会进入生产环境,生产将其依赖项基于锁定文件。

On the server you checkout this specific version or label, and run all the tests before replace the app, if the tests pass you continue the deployment.

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

If the test depend on dev dependencies, as composer do not have a test scope dependency, a not much elegant solution could be run the test with the dev dependencies (composer.phar install), remove the vendor library, run composer.phar install --no-devagain, this will use cached dependencies so is faster. But that is a hack if you know the concept of scopes in other build tools

如果测试依赖于开发依赖,因为 composer 没有测试范围依赖,一个不太优雅的解决方案可以使用开发依赖(composer.phar install)运行测试,删除供应商库,运行composer.phar install - -no-dev再次,这将使用缓存的依赖项,因此速度更快。但是,如果您知道其他构建工具中的作用域概念,那将是一种技巧

Automate this and forget the rest, go drink a beer :-)

自动化这个并忘记其余的,去喝啤酒:-)

PS.: As in the @Sven comment bellow, is not a good idea not checkout the composer.lock file, because this will make composer install work as composer update.

PS.:正如下面的@Sven 评论一样,不签出 composer.lock 文件不是一个好主意,因为这将使 composer install 像 composer update 一样工作。

You could do that automation with http://deployer.org/it is a simple tool.

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

回答by Abhi Beckert

On production servers I rename vendorto vendor-<datetime>, and during deployment will have two vendor dirs.

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

A HTTP cookie causes my system to choose the new vendor autoload.php, and after testing I do a fully atomic/instant switch between them to disable the old vendor dir for all future requests, then I delete the previous dir a few days later.

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

This avoids any problem caused by filesystem caches I'm using in apache/php, and also allows any active PHP code to continue using the previous vendor dir.

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



Despite other answers recommending against it, I personally run composer installon the server, since this is faster than rsync from my staging area (a VM on my laptop).

尽管其他答案反对它,但我个人还是composer install在服务器上运行,因为这比我的临时区域(笔记本电脑上的 VM)中的 rsync 快。

I use --no-dev --no-scripts --optimize-autoloader. You should read the docs for each one to check if this is appropriate on your environment.

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