为什么我永远不应该在生产中运行“composer update"?
composer install
将在 composer.lock
文件中说明时安装,但 composer update
将更新所有依赖项并创建一个 new composer.lock
文件基于 composer.json
中的要求.
composer install
will install whenever stated in the composer.lock
file, but composer update
will update all the dependencies and create a new composer.lock
file based on what is required in composer.json
.
很多人说只在开发中运行composer update
.但是我的问题是 composer update
确实替换了旧的 composer.lock
文件,如果您的应用程序要中断它会中断,因为可能与新更新的文件发生冲突依赖关系.
So many said only run composer update
in development. But my question is doing composer update
did replaced the old composer.lock
file, if your app is going to break it will break, because there might be conflict with the new updated dependencies.
我遇到了必须进行 composer update
的情况,该问题与 pcntl
扩展有关.唯一的解决方案是做 composer update
PHP pcntl 模块安装
I came across with a situation where I must do composer update
, the issue is related to pcntl
extension. The only solution is to do composer update
PHP pcntl module installation
我不明白为什么人们害怕在生产环境中运行 composer update
.
I don't understand why people are afraid of running composer update
on production.
推荐答案
TLDR;
不要在生产环境中运行 composer update
或 composer install
.在其他地方执行它并将结果上传到生产服务器,但不要上传到托管应用程序的同一目录.作为一般规则,您不应修改正在服务的应用程序同时.创建应用程序的不同副本,并在准备好后用最接近即时的命令替换它(例如 mv
或 ln -s
).
TLDR;
Do not run composer update
nor composer install
in production. Execute it somewhere else and upload the result to the production server, but not to the same directory where the application is hosted. As a general rule, you shouldn't modify the application that's being served while it's being served. Create a different copy of the application and when it's ready replace it with the closest to instantaneous command you can (e.g. mv
or ln -s
).
但如果您必须运行任何一个:始终运行 install
并创建全新安装;并且永远不要更新
.install
更加可预测和可靠,使用 update
您可以任由项目的任何依赖项摆布.
But if you HAVE to run either: always run install
and create a fresh installation; and never update
. install
is more predictable and reliable, with update
you are at the mercy of any of the project's dependencies.
Composer 以递归方式工作.因此,即使您在 composer.json
中有非常严格的版本限制,通过运行 composer update
您不仅会更新依赖项,还会更新依赖项的依赖项.
Composer works recursively. So even if you have very tight version constraints in your composer.json
, by running composer update
you would be updating not only your dependencies, but your dependencies' dependencies.
虽然大部分时间不会造成破损,但有时会.一个依赖项可能会引入一种行为变化,这可能会以您可能没有测试过的方式影响您的代码.
While most of the time this won't introduce breakage, sometimes it will. One dependency down the line may introduce a change of behaviour that may impact your code in a way you may have not tested against.
此外,它基本上使用了错误的工具来完成这项工作.Composer 是一个依赖管理工具,而不是一个部署工具.要将代码部署到生产环境,您应该使用某种代码部署工具(即使该工具"就像 FTP 上传和几个脚本一样简单).
Also, it's basically using the wrong tool for the job. Composer is a dependency management tool, not a deployment tool. To deploy your code to production you should be using some sort of code deployment tool (even if that "tool" is as simple as an FTP upload and a couple of scripts).
适当的流程是:
- 在您的开发机器上执行所有
require
和update
调用,您可以在其中毫无风险地测试项目.这会生成一个composer.lock
,这是整个项目的已知状态,具有离散的安装版本. - 通过
install --no-dev
创建一个新的 可安装版本.在此步骤中,您还应该转储优化的自动加载器、运行安装后脚本等.我通常将其分为多个步骤:
- Do all the
require
andupdate
calls on your development machine, where you can test the project without risk. This generates acomposer.lock
, which is a known state for the whole project, with discrete installed versions. - Create a new installable version doing
install --no-dev
. On this step you also should dump an optimized autoloader, run after-install scripts, etc. I usually separate this in more than one step:
composer install --prefer-dist --no-scripts --no-progress --no-suggest --no-interaction --no-dev
:
^^ 这用于完整、静默安装所有内容,不包括开发依赖项.
^^ This for a complete, silent installation of everything, excluding development dependencies.
composer dump-autoload --optimize --no-dev
^^ 转储适合生产的优化自动加载器脚本.
^^ To dump an optimized autoloader script suitable for production.
composer run-script --no-dev post-install-cmd
^^ 这主要用于 Symfony,但如果您有任何安装后脚本要运行(例如,将资产复制到公共"目录,预热某种类型的缓存,诸如此类),这将做这件事的好时机.
^^ This is mostly for Symfony, but if you have any post-install scripts to run (e.g. to copy assets to your "public" directory, warm-up some type of cache, anything like that), this would be a good moment to do it.
- 应测试上述步骤的结果(通常在暂存环境中),然后将其推送到整个生产环境(您的客户端代码、供应商文件夹、为产品量身定制的配置等);使用您喜欢的任何部署方法.
请注意,如果您使用任何慢";push 方法(FTP、复制、rsync
等),您不应该直接写入应用程序文件系统,而是创建应用程序的新副本,一旦文件传输准备好,请使用快速方法取代生产";随着新版本.一种流行且有效的方法是使用符号链接作为生产"链接.root,因此您只需要在 上述所有 完成并准备就绪后更新符号链接,而不会影响正在运行的应用程序(否则可能会暂时中断,因为突然包含属于不同的文件应用程序的版本).
Note that if you use any "slow" push method (FTP, copy, rsync
, etc), you shouldn't write directly to the application filesystem, but create a fresh copy of the application and once the file transfer is ready, use a quick method to replace "production" with the new release. A popular and effective way is use a symlink as "production" root, so you only need to update the symlink once all of the above is done and ready, without impacting a running application (that otherwise could be temporarily broken, by virtue of suddenly containing files that belong to different versions of the application).
相关文章