仓库部署和Composer:采用哪种工作流程?

19
作为 PHP 开发人员,我经常使用 Composer。过去,我只是在个人项目中使用它,所以没有遇到太多问题,但是现在在 Laravel 4 中使用时,需要部署的项目中出现了一些问题,我正在努力适应自己的工作流程。
我的所有项目都是 Git 仓库,因此按照惯例并且由于其仍然存在许多错误,像大多数开发人员一样,我将 vendor 目录放入了 .gitignore
现在的问题是:我也使用 Git 部署到服务器,而根据所有逻辑,vendor 目录不会被上传,因为它没有被存储在代码仓库中。
因此,我的问题是向那些已经比我更长时间使用 Composer 和 Git 的人提出的:保持服务器同步的最佳工作流程是什么?如何跟踪 vendor 文件夹而不真正跟踪它?
我尝试每次通过 Composer 更新时都上传它,但我的某些 vendor 文件夹非常大,我不能每次更新时手动上传 30Mb 的文件。
我真的不知道,你们是怎么解决这个问题的?我试着不忽略 vendor 文件夹,但是 Git 只会把它弄糊涂,一半被认为是克隆的仓库,反正被忽略了。
更新:请注意,我在共享主机上,因此无法访问服务器终端。
6个回答

9

在更新到最新代码后,最好的方法是在服务器上运行composer install。您还应该确保提交您的composer.lock文件,服务器将使用它来安装(不应在服务器上运行composer update)。


3
问题在于:我使用的是共享主机,无法访问服务器终端。 - Maxime Fabre
2
我遇到了一些相当长的安装时间,大约在2分钟左右。我甚至没有那么多依赖项 - 基本上只有两个。我不确定直接安装到生产环境是否是一个好主意,因为它可能会在完成时使您的应用程序停机几分钟。 - kalenjordan
3
Composer虽然有很多优点,但使用它来部署Magento项目确实很痛苦。我遇到了与这里提问者类似的问题。我知道Magento因其文件夹结构而相当特殊。因此,我使用composer在开发环境中安装,将所有内容放入git并进行部署。我知道这不是“最佳实践”或当前的思想,但很抱歉,我必须处理效率而不是额外的瓶颈。我也看到将所有内容放入git的好处。我可以检查依赖项是否有更改并预防问题。这是我的建议。 - Sylvain Rayé
2
@MaximeFabre 没有必要为任何人使用共享主机,这只适用于想要上传基本HTML的业余爱好者,而不是严肃的开发人员。购买一台服务器吧! - Sliq
1
@Jakobud,因为如果你这样做,你可能会在生产环境中得到与开发时不同版本的依赖项,这可能会引入新的错误,而你没有测试过,并且意外地破坏你的生产环境。 - Seldaek
显示剩余7条评论

4

我正在服务器上的git post-receive hook中处理类似这样的问题。这个还没有测试,可能会有bug,但你应该能明白思路。

#!/bin/bash
# get the updated composer.json
git checkout master -- composer.json

# only do this stuff if composer.json is different
# you could check this manually, or with git or cmp
cp composer.json tmp/composer.json

# may take a minute, but won't take the site down
(cd tmp; composer install --prefer-dist)

# this doesn't seem to be atomic
git checkout -f

# switch vendors over
# this isn't quite an atomic operation, but is very close
# you could probably do it with symlinks and "mv -Tf" to make it atomic
mv vendor vendor.old
mv tmp/vendor vendor

rm -r tmp vendor.old

理想情况下,所有部署的操作(即在此情况下的git checkoutcomposer install)都应该在www之外的隔离环境中进行,除了一个mv操作。如果您的工作树中有未跟踪的文件(例如CMS上传文件),并且依赖于PHP的__FILE__不能解析符号链接(由于这个PHP bug),那么这种方法将不起作用。

请注意:Composer在使用require-dev时更改了install的行为,因此我已经在这里提出了同样的问题。我的问题上有赏金。我恳请您在那里添加一个答案,因为您显然知道自己在说什么 :) - Sliq

4

Capistrano(如果您使用Symfony2,则为Capifony)对于使用composer进行部署非常有用。您可以远程触发部署,并在隔离环境中运行composer install,因此站点仍然在线直到成功部署为止。还有许多其他好处,例如保留先前的部署并回滚、在部署之前复制旧供应商、编译资产等等。


2

这是一个老问题,但如果有人正在寻找解决方案:

我稍微修改了@dave1010的答案,使用git pull代替git checkout--force

#!/bin/bash
# get only composer files 
git fetch
git checkout origin/master -- composer.json
git checkout origin/master -- composer.lock

# make sure tmp is empty
rm -rf tmp
mkdir tmp

# copy the composer files to tmp
cp -r vendor tmp/vendor
cp composer.json tmp/composer.json
cp composer.lock tmp/composer.lock

# may take a minute, but won't take the site down
(cd tmp; composer install --no-scripts --verbose; cd ..)

# switch vendors over
rm -rf vendor_old
mv vendor vendor_old
mv tmp/vendor vendor

# update your code
git pull

# run again composer install. This time will print 'Nothing to install or update'
# but will execute pre/post scripts & generate autoload files
composer install --optimize-autoloader

也许使用 capistrano/composer 可能会有更好的解决方案。但我更喜欢我的方法。

1
你可以使用像Jenkins这样的工具来通过FTP上传文件。这样,你可以直接指示Jenkins在服务器上运行composer install,然后将文件通过FTP传输过去。
这也允许你忽略vendor文件夹。
它需要创建一个构建服务器,并且你需要能够对构建服务器执行命令。

-1

关键在于你的 composer.lock 文件。composer.lock 文件记录了你安装的所有软件包(及其版本)的详细信息。当你部署应用时,同样将 composer.lock 文件上传到生产服务器上,并执行 composer update 命令即可,系统会自动安装相同版本的所有软件包。使用像 Capistrano 或 Flightplan 这样的部署工具,可以将 composer update 步骤作为流程的一部分,以便实现自动化。


1
@Seldaek的帖子建议不要在生产服务器上使用composer update。这里有很好的解释https://dev59.com/G2Ei5IYBdhLWcg3wCoUp - Carlton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接