教程:将实时项目从 Forge 迁移到 Envoyer

发布日期:作者:

Tutorial: Moving live projects from Forge to Envoyer image

一般来说,我会尽量减少使用付费服务。如果它们能带来显著价值,我会集成它们,因为作为一家自筹资金的创始公司,成本会迅速累积。我也会尽量减少服务器管理工作,因为它会让我变得暴躁。

最近,我将我的实时项目从 Forge 迁移到 Envoyer 进行部署。由于这些项目是实时应用,并被客户积极使用,我希望迁移过程尽可能无缝且停机时间尽可能短。

在这篇文章中,我想分享完成此操作的步骤。首先,我会解释我决定迁移的一些背景。如果您想深入了解迁移步骤,可以跳过第一部分。

背景

使用 Forge 进行部署大约需要 10 到 20 秒。我的项目有一个 API,流量越来越多,而且我每周都会发布几次更改,这很快就累积到我开始收到来自监控服务的停机时间通知。

我还想在部署过程中添加更多步骤,例如 npm cinpm run production,这会增加更多停机时间。

所以,是时候进行零停机时间部署了,这是 Envoyer 的主要卖点。但是,还有一些其他优势,它们也会为部署过程带来很大的价值,而且我之前没有真正想过。

如果出现问题(肯定会出现问题),您的应用程序不会一直处于维护模式

在部署脚本开始时使用 php artisan down 将应用程序置于维护模式,然后以 php artisan up 结束以将其从维护模式中取出,这很常见。

但是,如果在这两者之间出现问题,应用程序将保持在维护模式,因为它永远不会到达 php artisan up。因此,您必须将应用程序从维护模式中取出,并调查出现问题的原因。使用 Envoyer,如果部署过程中的任何步骤出现故障,整个过程将被取消,您的应用程序仍然可以正常运行。

重新部署部署

如果您的应用程序在任何时候引入了 bug,您需要将其恢复到工作状态,只需单击一次,即可重新部署之前的部署。使用 Laravel Forge,您的生产环境将出现 bug,无法轻松回滚。

配置构建和部署步骤

虽然您可以使用 Forge 通过部署脚本执行此操作,但这总感觉像是在玩火。使用 Envoyer,一切变得轻松、有序且可拖放。

让您的生活更轻松

由于部署现在是零停机时间,您可以将更多步骤添加到这些部署中,这将使您的部署生活更轻松。例如,我有一些文件需要复制到 CDN。现在,我可以通过在部署过程中运行 artisan 命令来执行此操作,使用部署钩子。太棒了!

还有一些其他功能,例如健康检查和心跳,但这些是主要优势。让我们继续迁移。

步骤 1:基础知识

我不会详细介绍,因为这真的很简单。首先在 Envoyer 中执行以下操作:连接您选择的源代码管理(例如 Github)并创建一个项目。

提示:如果您想保存超过四个最近的部署,请转到您的项目 > 设置,并将保留的部署数量增加。

注意:以下步骤假设您在 Forge 中的网站目录设置为 /public,而不是其他目录。您可以通过转到 Forge 中的网站,然后转到侧边栏菜单中的元数据,然后转到网站目录来查看。如果您有 /public 之外的任何目录,请在执行后续步骤时牢记这一点。

步骤 2:导入您的 Forge 服务器

以前,这需要多个步骤,包括复制 IP 地址和添加 SSH 密钥,但是 Laravel 团队现在简化了这个过程。

  • 转到 Forge 中的账户(右上角),从侧边栏菜单中转到 API,并创建一个令牌(可以将其命名为 Envoyer)。
  • 然后,转到 Envoyer 中的账户(右上角),从侧边栏菜单中转到集成,并使用刚生成的令牌连接到 Forge。
  • 转到您的项目,单击服务器,然后单击导入 Forge 服务器,并选择要导入的网站。

完成!

步骤 3:首次部署

现在,您可以真正开始部署了。不用担心,因为这次部署还不会生效,我们将在后面进行操作。但是,这将有助于您更好地理解底层原理,因为您可以查看旧文件结构和新文件结构。由于目前还没有任何内容生效,因此它是测试一切正常工作的一个好方法。

我们将在最后一步将我们的实时应用程序从 Forge 切换到 Envoyer。

步骤 4:了解新的文件结构

您的网站目录

让我们看看现在的情况。SSH 登录到您的 Forge 服务器,并转到您的网站目录(下面显示为 example.com)。它看起来像这样。

drwxrwxr-x 15 forge forge   4096 Dec 21 16:27 ./
drwxr-xr-x 11 forge forge   4096 Dec 21 16:26 ../
-rw-rw-r--  1 forge forge   2417 Dec 15 22:04 .env
drwxrwxr-x  8 forge forge   4096 Dec 19 14:07 .git/
-rw-rw-r--  1 forge forge    111 Jul  3 19:12 .gitattributes
-rw-rw-r--  1 forge forge    214 Dec  9 15:30 .gitignore
-rw-rw-r--  1 forge forge    174 Jul  3 19:12 .styleci.yml
-rw-rw-r--  1 forge forge   1607 Nov  9 14:07 README.md
drwxrwxr-x 14 forge forge   4096 Nov  9 14:07 app/
-rw-rw-r--  1 forge forge   1686 Jul  3 19:12 artisan
-rw-rw-r--  1 forge forge    187 Jul  3 19:12 auth.json
drwxrwxr-x  3 forge forge   4096 Jul  3 19:12 bootstrap/
-rw-rw-r--  1 forge forge   2850 Dec 16 13:32 composer.json
-rw-rw-r--  1 forge forge 396382 Dec 19 14:07 composer.lock
drwxrwxr-x  2 forge forge   4096 Dec 17 11:51 config/
lrwxrwxrwx  1 forge forge     46 Dec 21 16:27 current -> /home/forge/example.com/releases/20201221152610/
drwxrwxr-x  6 forge forge   4096 Nov 17 13:46 database/
drwxrwxr-x  3 forge forge   4096 Jul  3 19:12 nova-components/
-rw-rw-r--  1 forge forge 450772 Dec 15 22:35 package-lock.json
-rw-rw-r--  1 forge forge   1059 Nov 17 13:46 package.json
-rw-rw-r--  1 forge forge   1405 Jul  3 19:12 phpunit.xml
drwxrwxr-x 11 forge forge   4096 Dec 19 14:07 public/
drwxrwxr-x  9 forge forge   4096 Dec 21 16:26 releases/
drwxrwxr-x  6 forge forge   4096 Jul  3 19:12 resources/
drwxrwxr-x  2 forge forge   4096 Dec 19 14:07 routes/
-rw-rw-r--  1 forge forge    563 Jul  3 19:12 server.php
drwxrwxr-x  7 forge forge   4096 Nov  9 14:39 storage/
drwxrwxr-x  4 forge forge   4096 Jul  3 19:12 tests/
drwxrwxr-x 67 forge forge   4096 Dec 19 14:07 vendor/
-rw-rw-r--  1 forge forge    683 Jul  3 19:12 webpack.mix.js

您在网站文件夹(example.com)中看到的是通过 Forge 部署的网站。

新的 Envoyer 目录

Envoyer 创建了两个新的目录。

current 文件夹是最新发布目录的符号链接。这就是部署的工作方式:创建一个新的发布目录,而 current 目录将链接到它。

releases 文件夹包含所有部署。文件夹的名称是时间戳。

新结构

如果您现在进入 current 目录,您会注意到两件事。

.env 链接回 /home/forge/example.com/.env

以及

/storage 链接回 /home/forge/example.com/storage

这意味着这些文件不会在每次部署时被覆盖,因此存储在 storage 中的文件和缓存将保持原样,当然,您的 .env 文件将保留在本地,供每次部署使用。

步骤 5:链接存储文件夹

这让我们进入步骤 5。请记住,当您第一次通过 Forge 部署时,您是否运行了 php artisan storage:link?对于您通过 Envoyer 进行的新部署,也需要此链接。问题是,每次新的部署都会导致您不得不重新运行它,因为每次部署都是您应用程序的新副本,位于新的文件夹中。

幸运的是,Envoyer 提供了一个设置来永久设置此链接。转到您的项目,部署钩子,并单击管理链接文件夹。将 public/storage 链接到 storage/app/public

步骤 6:Horizon、调度程序和守护进程

如果您在 Forge 中设置了这些,您将知道它们是什么以及为什么要设置它们。它们运行在一个文件夹中,这个文件夹仍然是您 Forge 部署所在的“旧”文件夹。让我们将您需要的调度程序和守护进程添加到 Envoyer 文件夹中。

调度程序

在 Forge 中,转到您的服务器,对于每个调度程序,如果其路径包含 /home/forge/example.com(其中 example.com 是您的网站),请复制这些调度程序,并创建一个新的调度程序,将路径中的 current 添加到路径中:/home/forge/example.com/current

例如,

php /home/forge/example.com/artisan schedule:run

将变为

php /home/forge/example.com/current/artisan schedule:run

之所以说复制,是因为您当前的应用程序(通过 Forge 部署)仍在运行,并使用调度程序。因此,请添加新的调度程序,一旦您完成了迁移到 Envoyer 的工作(本指南中的最后一步),您可以删除旧的调度程序。

注意:这些调度程序现在将在两个应用程序上运行(当前的 Forge 应用程序和新的 Envoyer 应用程序)。我没有遇到任何问题,但如果你有大量进程非常频繁地运行(例如,每分钟一次),那么请先检查你希望如何协调这些进程。例如,你可以先复制调度程序,并将部署作为最后一步执行。

守护程序

守护程序也是一样,其中 Directory 值应该是 /home/forge/example.com/current

这里也是:添加新的,不要更新现有的。

Laravel Horizon

如果你使用 Horizon,你可能在部署时运行 php artisan horizon:terminate。你可以通过转到你的项目、部署钩子,然后选择添加钩子来将其添加到 Envoyer。

为其命名,以 Forge 身份运行,然后添加

cd {{ release }}
php artisan horizon:terminate

第一行是为了确保它进入新部署的刚添加的目录中,以便在那里运行命令。

确保选择服务器并点击保存钩子。

步骤 7:我们上线了吗?

还没有,但让我们现在就做!我们现在可以将 Web 目录切换到新的 current 目录,该目录符号链接到最新版本。

在 Forge 中,转到你的网站,从侧边菜单中选择 Meta,然后转到 Web 目录。将此更新为 /current/public

恭喜,你现在拥有零停机时间部署。

额外步骤

删除旧文件

正如你可能已经发现的那样,现在你的应用程序在网站文件夹(**example.com**)中有一个未使用的副本,因为 Envoyer 部署在 **example.com/current** 中。这意味着你可以选择删除旧文件。

你可以删除所有内容,除了

  • 文件夹 **current**
  • 文件夹 **releases**
  • 文件夹 **storage**
  • 文件 **.env**

为什么我的 releases 文件夹没有像我在 Forge 上那样有一个 .git 文件夹?

在你的先前 Forge 部署中,有一个 .git 文件夹,因为 Forge 会从你的源代码控制存储库中拉取。Envoyer 不会这样做。相反,它会下载你仓库的 tarball,然后将其解压缩到相关的 releases 文件夹中。

添加部署钩子

我们已经简单地介绍过 Horizon,但你可以添加任何你喜欢的部署钩子。

诸如运行 npm cinpm run production 之类的事情很有用,但你也可以创建自己的自定义 artisan 命令并在部署时运行它们。例如,一个清除 Redis 缓存中你自己的缓存项的命令。由于你现在拥有零停机时间部署,因此将这些内容移动到部署过程中非常方便。

希望这可以帮助你将你的生产应用程序从 Forge 迁移到 Envoyer。享受那些甜蜜的零停机时间部署!如果你想注册 Envoyer,你可以在这里这样做。


作者:Joost 来自 Freddy Feedback

Joost photo

产品经理转型为 Freddy Feedback 的独立创始人。

Cube

Laravel 新闻

加入 40k+ 其他开发人员,绝不错过新的提示、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理你的服务器,并在几秒钟内部署你的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和对本地和生产环境的即时反馈进行微调。

Tinkerwell
No Compromises logo

不妥协

Joel 和 Aaron 是来自 No Compromises 播客的两位经验丰富的开发人员,现在可以为你的 Laravel 项目聘用。⬧ 固定费用 7500 美元/月。⬧ 没有冗长的销售流程。⬧ 没有合同。⬧ 100% 退款保证。

不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,以确保你的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

正在运行旧的 Laravel 版本?即时、自动的 Laravel 升级和代码现代化,以保持你的应用程序更新。

Shift
Bacancy logo

Bacancy

让你的项目充满活力,每月只需 2500 美元即可获得 4-6 年经验的经验丰富的 Laravel 开发人员。获得 160 小时的专业知识和 15 天无风险试用。立即安排电话!

Bacancy
Lucky Media logo

Lucky Media

立即获得幸运 - 拥有十年以上经验,是 Laravel 开发的理想选择!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 的电子商务。一个开源软件包,将现代无头电子商务功能的力量带到 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 职位网站

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,它包含运行现代 SaaS 所需的所有功能。付款、漂亮的结账、管理面板、用户仪表板、身份验证、现成的组件、统计数据、博客、文档等等。

SaaSykit:Laravel SaaS 启动工具包
Rector logo

Rector

你无缝升级 Laravel、降低成本和加速创新的合作伙伴,为成功公司服务

Rector
MongoDB logo

MongoDB

使用 MongoDB 和 Laravel 的强大集成来增强你的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。了解 MongoDB 的灵活、现代数据库如何改变你的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的无依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到你的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel 提示构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包为你的 Laravel 应用程序添加评论

阅读文章