>백엔드 개발 >PHP 튜토리얼 >Rocketeer: PHP 애플리케이션 배포를 위한 최고의 도구

Rocketeer: PHP 애플리케이션 배포를 위한 최고의 도구

WBOY
WBOY원래의
2023-08-30 14:21:021201검색

Rocketeer:部署 PHP 应用程序的终极工具

PHP 개발자가 일반 웹 애플리케이션용 배포 도구를 사용해야 했던 때가 있었습니다. 예를 들어 Capistrano를 사용하여 Laravel 애플리케이션을 배포하는 방법에 대한 Johannes Schickling의 튜토리얼에서 이를 확인할 수 있습니다. 이는 Ruby 도구이므로 Ruby 코드를 작성해야 합니다. 이러한 도구는 작업을 완료하지만 PHP 애플리케이션과의 통합이 제한적입니다. 이로 인해 일부 시나리오에서는 솔루션이 좋지 않을 수 있습니다.

하지만 요즘에는 더 깊은 통합을 가능하게 하는 우리 언어로 작성된 일부 배포 도구를 갖게 된 행운이 있습니다. Rocketeer는 Capistrano 및 Laravel 프레임워크에서 영감을 받은 도구 중 하나입니다.

Rocketeer는 배포 요구 사항에 대한 탁월한 접근 방식을 제공하는 최신 도구입니다. 즉, 다양한 환경과 서버에서 작업을 실행하고 애플리케이션을 관리합니다. 게다가 composer.json 파일이 감지되면 Composer 종속성을 설치하는 것과 같은 마법도 있습니다. 최신 PHP 애플리케이션의 경우 정상적인 기본값과 일반적인 작업의 자동화를 얻을 수 있습니다. 그리고 모든 것을 사용자 정의하고 확장할 수 있습니다.

클라이언트에서 실행되는 SSH 작업 실행기로 설명할 수 있습니다. 이 명령은 SSH 연결을 통해 서버에서 실행됩니다. 불행하게도 FTP 액세스만 가능한 공유 호스팅 제공업체를 사용한다면 운이 좋지 않습니다. 도구가 코드를 가져올 수 있는 원격 저장소도 필요합니다. Git과 SVN은 기본적으로 지원됩니다. 다른 버전 제어 시스템의 지원이 필요합니까? 제공된 인터페이스를 사용하여 자신만의 구현을 작성하세요.

설치

Rocketeer는 두 가지 방법으로 설치할 수 있습니다. phar 파일을 다운로드하여 실행 가능하게 만들거나 Composer를 통해 설치할 수 있습니다. 나는 후자를 지지한다. 이를 종속성으로 두면 저장소를 복제할 때 쉽게 설치할 수 있습니다. 이는 리포지토리를 복제하여 시작하고 실행하는 모든 사람에게 도움이 될 수 있습니다.

Composer를 사용하여 설치:

으아아아

글로벌하게 설치하는 것을 권장하지 않습니다. 이를 저장소 수준으로 유지하면 모든 배포자가 동일한 버전을 실행하게 됩니다. 이 바이너리를 사용하려면 vendor/bin 添加到您的 PATH 中。然后,您可以通过在项目根目录中输入 rocketeer를 사용하는 것이 좋습니다.

라이트 업

시작해 보세요! 구성을 위해 디렉터리와 파일을 부팅하는 것부터 시작하세요. 프로젝트 루트 디렉터리에서 rocketeer ignite를 실행하면 됩니다.

애플리케이션이 시작되면 도구는 프로젝트에 .rocketeer 폴더를 생성합니다. 디렉토리의 내용은 다음과 같습니다:

으아아아

배포 설정을 시작하는 데 필요한 모든 구성 파일은 다음과 같습니다. 여기에서 구성 파일을 참조할 때마다 해당 파일은 .rocketeer/ 디렉터리에 존재합니다.

원격 폴더 구조

Rocketeer가 서버 측에서 폴더 구조를 관리하는 방법을 이해하는 것이 중요합니다. 이는 일반 설정과 약간 다르기 때문입니다. 몇 개의 디렉터리를 사용하여 배포의 특정 측면을 관리하므로 작업을 효율적으로 수행할 수 있습니다. 서버에 애플리케이션을 배포하려는 경로를 지정하면 도구가 나머지를 처리합니다. /var/www/app를 응용 프로그램 디렉터리로 사용한 경우 폴더는 다음과 같습니다.

으아아아

가장 중요한 폴더는 최신 버전을 가리키는 current입니다. 이것은 웹 서버의 문서 루트가 설정되어야 하는 곳입니다. 그러면 배포할 때 어떻게 되나요?

  1. 이 도구는 releases 디렉터리에 타임스탬프가 있는 폴더를 생성합니다.
  2. 출판 준비를 위한 모든 작업을 완료하세요.
  3. 심볼릭 링크를 새 버전으로 업데이트 current하세요.

이 프로세스를 통해 배포가 사용자에게 투명해집니다. 버전 간 전환은 거의 즉각적이며 원자 배포라고도 합니다.

일부 데이터는 배포 간에 유지되어야 합니다. 예를 들어 파일 업로드, 사용자 세션 및 로그가 될 수 있습니다. 이러한 파일이나 폴더는 shared 디렉터리로 이동됩니다. 이 도구는 구성한 버전에 대해 각 버전에 심볼릭 링크를 생성합니다.

활동

이벤트 중심 도구, 모든 전략과 작업은 이전 이후 런타임에 트리거됩니다. 또한 작업이 실패할 경우 특별한 pause 이벤트를 제공합니다. 예를 들어 일반적인 오류의 경우 dependency.haltdeploy.halt가 될 수 있습니다. 이를 통해 필요한 곳에 프로세스를 연결할 수 있습니다.

배포 중에 발생하는 기본 이벤트는 다음과 같습니다.

  • deploy.before:在任何事情发生之前。
  • create-release.before:在创建新的发布目录之前。
  • create-release.after:创建新的发布目录后。
  • dependency.before:在安装或更新依赖项之前。
  • dependency.after:安装或更新依赖项后。也许请确保供应商文件夹中的二进制文件是可执行的。
  • test.before:运行测试之前。
  • test.after:运行测试后。
  • migrate.before:运行数据库迁移之前。也许您想备份数据库?
  • migrate.after:运行数据库迁移后。
  • deploy.before-symlink:在将版本符号链接为当前版本之前。
  • deploy.after:已完成。您可以通知人们一切顺利或其他情况。

我们还可以创建自己的事件,我们可以触发和监听这些事件。目前,我们将坚持为我们提供的这些事件。现在它们对我们来说就足够了。

任务

在 Rocketeer 的核心,我们发现了一个名为“任务”的概念。幕后发生的大部分事情都是核心任务。任务的定义可以是作为部署中的步骤执行的一组指令。如果我们查看该工具提供的一些类,我们可以大致了解什么是任务:诸如 DeploySetup迁移、 class="inline">回滚 和 class="inline">依赖项。当您部署时,部署命令本身就是一个带有子任务的任务。

任务类型

在这里,您将开始了解该工具与 PHP 的集成程度,因为您将用该语言编写任务。您可以通过三种不同的方式创建自己的任务:

任意终端命令。这些是您想要在服务器上运行的单行代码。对于很多事情都很有用,例如运行 gulp build ---development

关闭。如果您需要更多的灵活性或复杂性,您可以将任务编写为闭包(匿名函数)。假设您想在部署期间为 API 生成文档。

function($task) {
    return $task->runForCurrentRelease('apigen generate  source src  destination api');
}

课程。对于更复杂的任务,您应该利用该选项为任务创建类。您创建一个类并扩展 Rocketeer\Abstracts\AbstractTask。然后,您必须至少提供说明和 execute() 方法。这是一个完全无用的示例,只是为了显示任务类的结构:

namespace MyDeployableApp\Deploy\Tasks;

class HelloWorld extends \Rocketeer\Abstracts\AbstractTask
{
    /**
     * Description of the Task
     *
     * @var string
     */
    protected $description = 'Says hello to the world';

    /**
     * Executes the Task
     *
     * @return void
     */
    public function execute() {
        $this->explainer->line('Hello world!');

        return true;
    }
}

请注意,您必须自己注册任务类。您可以通过 hooks.php 文件执行此操作,并将其添加到 custom 数组...

'custom' => array('MyDeployableApp\Deploy\Tasks\HelloWorld',),

...或者您可以通过外观来做到这一点:

Rocketeer::add('MyDeployableApp\Deploy\Tasks\HelloWorld');

注册后,就可以执行它:

$ rocketeer hello:world
staging/0 | HelloWorld (Says hello to the world)
staging/0 |=> Hello world!
Execution time: 0.004s

定义任务

我们首先讨论事件,因为我们将任务挂接到流程中需要它们的地方。您可以通过几种方式来做到这一点。选择您喜欢且满足您的复杂程度要求的一个。

定义任务的最简单方法是在 hooks.php 文件中。它为此提供了两个数组,指定在某些事件之前或之后执行任务。

'before' => [
    'setup' => [],
    'deploy' => ['hello:world'],
    'cleanup' => [],
],

策略

您可能已经知道所提供的任务非常通用。以 依赖项 为例。我们谈论的是哪种依赖关系以及哪个包管理器?

这就是策略发挥作用的地方。策略是任务的具体实现,例如使用 Behat 运行测试或使用 Gulp 构建前端。任务有一个默认策略,可以选择通过 CLI 运行其他策略。我们可以这样列出可用的策略:

$ rocketeer strategies
+--------------+----------------+-----------------------------------------------------------------------+
| Strategy     | Implementation | Description                                                           |
+--------------+----------------+-----------------------------------------------------------------------+
| check        | Php            | Checks if the server is ready to receive a PHP application            |
| check        | Ruby           | Checks if the server is ready to receive a Ruby application           |
| check        | Node           | Checks if the server is ready to receive a Node application           |
| deploy       | Clone          | Clones a fresh instance of the repository by SCM                      |
| deploy       | Copy           | Copies the previously cloned instance of the repository and update it |
| deploy       | Sync           | Uses rsync to create or update a release from the local files         |
| test         | Phpunit        | Run the tests with PHPUnit                                            |
| migrate      | Artisan        | Migrates your database with Laravel's Artisan CLI                     |
| dependencies | Composer       | Installs dependencies with Composer                                   |
| dependencies | Bundler        | Installs dependencies with Bundler                                    |
| dependencies | Npm            | Installs dependencies with NPM                                        |
| dependencies | Bower          | Installs dependencies with Bower                                      |
| dependencies | Polyglot       | Runs all of the above package managers if necessary                   |
+--------------+----------------+-----------------------------------------------------------------------+

制定自己的策略

假设您正在为您的应用程序使用 BDD With Behat,而不是 TDD。然后您想使用 Behat 而不是 PHPUnit 来运行测试。由于它是一个测试运行程序,因此已经有一个策略命名空间,但没有实现。创建目录 .rocketeer/strategies/ 并将新的 BehatStrategy.php 放入其中。

namespace MyDeployableApp\Deploy\Strategies;

use Rocketeer\Abstracts\Strategies\AbstractStrategy;use Rocketeer\Interfaces\Strategies\TestStrategyInterface;

class BehatStrategy extends AbstractStrategy implements TestStrategyInterface
{
    public function test() {
        return $this->binary('vendor/bin/behat')->runForCurrentRelease();
    }
}

您现在可以将测试策略切换到 strategies.php 中的新实现。

'test' => 'Behat',

连接和阶段

您是否拥有或已经考虑过基础设施并不重要。如果您的应用程序部署到许多服务器上的许多环境中,这并不重要。火箭人将随时为您服务。您甚至可以在同一服务器上拥有许多不同的位置。这就是术语“连接”和“阶段”的用武之地。

连接是您部署应用程序的服务器。这通常称为环境,生产和登台就是这样的例子。在该工具中配置这些连接是轻而易举的事。您可以通过嵌套数组或为每个连接保留单独的文件来完成此操作。每个连接中还可以有多个服务器。

阶段就像连接中的连接,一种“连接感知”。您可以使用阶段在单个服务器上设置暂存和生产环境。因此,您将拥有一个包含两个阶段的连接,而不是两个单独的连接。

插件

一个很棒的功能是我们可以使用插件扩展我们的流程。有一些官方的可以与 Laravel、Slack、HipChat 和 Campfire 集成。 Packagist 上也有一些,但不是很多。通过 CLI 安装插件是一项简单的任务:

$ rocketeer plugin:install rocketeers/rocketeer-slack

尽管插件数量有限,但为将来开发插件留下了空间。它讲述了一个很好的哲学。为什么不开发自己的一款呢?

设置您的部署

为了让您的应用程序启动,您需要一些基本配置。您需要告诉 Rocketeer 在哪里可以找到您的应用程序以及应该将其部署到哪里。首先,我们在 config. 中设置应用程序名称并配置生产服务器。

'application_name' => 'my-deployable-app',

// [...]

'connections' => [
    'staging' => [
        'host' => 'staging.my-deployable-app.com',
        'username' => '',
        'password' => '',
        'key' => '/Users/niklas/.ssh/id_rsa',
        'keyphrase' => '',
        'agent' => '',
        'db_role' => true,
    ],
    'production' => [
        'host' =>
        'www.my-deployable-app.com',
        'username' => '',
        'password' => '',
        'key' => '/Users/niklas/.ssh/id_rsa',
        'keyphrase' => '',
        'agent' => '',
        'db_role' => true,
    ],
],

您现在拥有应用程序名称和用于部署应用程序的服务器。此设置使用 SSH 密钥身份验证,但您也可以使用用户名和密码进行连接。要提示输入用户名和密码,请设置 'key' => ''。该工具会将凭据存储在您的本地计算机上,并在以后每次使用它们。我不建议在配置文件中设置用户名和密码,因为您永远不希望将凭据提交到您的存储库。

您现在应该做的是更改部署到的默认连接。将默认设置设置为生产并不理想。您不想意外地部署到生产中。因此,在同一文件中,查找 default 键并将值更改为 staging

'default' => ['staging'],

应用程序名称本身并不那么重要。但如果您没有指定要部署到的文件夹,它将使用它作为根目录中的文件夹名称。默认情况下,根目录设置为 /home/www。使用此应用程序名称,它将部署到 /home/www/my-deployable-app。如果您想更改根目录,可以在 remote. 中进行更改。

// Deploys to /var/www/my-deployable-app/
'root_directory' => '/var/www/',

在同一文件中,您可以覆盖应用程序名称并为应用程序指定目录。

// Deploys to /var/www/tutsplus-tutorial
'app_directory' => 'tutsplus-tutorial',

现在您已经有了部署的接收端,但您还需要设置代码的位置,以便可以提取它。您可以通过在 scm.php 中设置远程存储库来执行此操作。默认情况下它使用 Git,但它也支持 SVN。您告诉它我们的存储库的地址,并在需要时提供凭据。我建议您在这里也使用 SSH 密钥身份验证,并将用户名和密码留空。

'repository' => 'git@github.com:owner/name.git',
'username'   => '',
'password'   => '',
'branch'     => 'master',

由于您添加了到生产服务器的连接,因此您想要部署 master 分支。

连接和阶段特定配置

在大多数情况下,您不希望所有连接或阶段都使用相同的配置选项。例如,您想要将另一个分支部署到临时环境。 Rocketeer 允许您使用 config.php 覆盖连接和阶段的配置值。要在暂存连接上部署名为“暂存”的分支,请执行以下操作:

'on' => [
    'connections' => [
        'staging' => [
            'scm' => [
                'branch' => 'staging',
            ]
        ]
    ],
],

它使用嵌套数组来覆盖配置值。在 staging 键下,找到要更改的文件中的相应键。在本例中,它是 branch,位于 scm.php

部署,起飞!

现在您已完成成功部署所需的一切设置。您尚未满足完整部署的要求,但足以将应用程序克隆到服务器并提供给最终用户。首先,您可以执行检查策略来查看您的服务器是否满足要求。

$ rocketeer check

如果一切正常,您可以通过运行进行部署:

$ rocketeer deploy

由于这是您的第一次部署,Rocketeer 将确保一切都达到标准。该工具创建它所需的目录以及我们的应用程序将驻留在其中的目录。如果一切顺利,您应该在服务器上拥有完整的应用程序构建。

如果您在上一节中将默认连接更改为暂存,则它将始终部署到暂存。当然,除非您告诉它部署到其他地方。当您想要在不同的连接或多个连接上进行部署时,可以使用 --on 开关。

# Deploy to production
$ rocketeer deploy --on="production"

# Deploy to staging and production
$ rocketeer deploy --on="staging,production"

想看看按下按钮后您的服务器上会发生什么吗?使用 --pretend 标志让该工具告诉您它将在服务器上执行什么。

$ rocketeer deploy --pretend

休斯顿,我们遇到了问题。我们需要回滚。

不幸的是,我们需要处理会破坏功能或对基础设施造成严重破坏的部署。然后您需要快速回滚到最新版本。幸运的是,这是一个简单的操作 - 只需运行命令:

$ rocketeer rollback

由于它存储了许多构建,因此执行回滚速度很快。它将 current 的符号链接更改为以前的版本。

共享目录

设置共享目录很简单 - 只需将它们添加到 shared 数组(位于 remote.php 中)。 Rocketeer 将在之后的部署中为您创建并链接这些文件夹。指定的路径应该相对于您的根文件夹。

'shared' => [
    'storage/logs',
    'storage/sessions',
    'storage/uploads',
    '.env',
],

可写目录

大多数共享目录还需要 Web 服务器能够写入它们。写入日志、会话或文件上传通常是任何应用程序执行的任务。您可以将这些内容添加到 remote.php 中的 permissions.files 数组中。

'permissions' => [
    'files' => [
        'storage/sessions',
        'storage/logs',
        'storage/uploads',
    ],
    // [...]
],

安装或更新依赖项

如果应用程序依赖于任何类型的依赖项,则需要安装或更新依赖项。该工具支持最流行的包管理器。如果您有默认设置,则无需进行任何配置。它将检测并安装或更新 Composer、Npm、Bower 和 Bundler 的依赖项。 依赖项 的默认策略设置为 Polyglot。这是该工具检测和安装不同包管理器依赖项的方法。

但是,假设您想要在 staging 上安装所有依赖项,并且该工具默认使用 --no-dev 标志。也许您想安装 PHPUnit 来运行测试,这是一个开发依赖项。在 strategies.php 中,您可以找到 composer 键,它告诉工具如何执行 Composer。然后,您可以在 config.php 中覆盖此设置:

use Rocketeer\Binaries\PackageManagers\Composer;

// [...]

'on' => [
    // [...]
    'connections' => [
        'staging' => [
            'strategies' => [
                'composer' => [
                    'install' => function (Composer $composer, $task) {
                        return $composer->install([], ['--no-interaction' => null, '--prefer-dist' => null]);
                    }
                ],
            ],
        ]
    ],
],

数据库迁移

当您拥有完整的版本时,在符号链接到当前版本之前,迁移数据库通常是您想要做的事情。无论您使用什么工具,您都可以让它在 deploy.before-symlink 之前运行。这个钩子不是普通的钩子,而是一个内部钩子。然后,您需要在 hooks.php 以外的其他地方注册它。您可以在 events.php 中执行此操作,如果该文件尚不存在,则可以创建该文件。

use Rocketeer\Facades\Rocketeer;

// Laravel
Rocketeer::addTaskListeners('deploy', 'before-symlink', function ($task) {
    $task->runForCurrentRelease('php artisan migrate');
});

// Symfony2
Rocketeer::addTaskListeners('deploy', 'before-symlink', function ($task) {
    $task->runForCurrentRelease('php app/console doctrine:migrations:migrate');
});

// Stand-alone Doctrine
Rocketeer::addTaskListeners('deploy', 'before-symlink', function ($task) {
    $task->runForCurrentRelease('doctrine migrations:migrate --no-interaction');
});

运行测试

在部署过程中运行测试是确保不会出现损坏的代码或测试的好方法。默认情况下,该工具使用 PHPUnit,您可以在安装或更新依赖项后挂钩测试运行器来运行。

'after' => [
    'setup'        => [],
    'deploy'       => [],
    'dependencies' => ['test'],
    'cleanup'      => [],
],

我们现在应该看到它在每个部署上执行 PHPUnit,并且如果测试失败,它将中止。确保您看到它的输出,否则在查找 PHPUnit 二进制文件或测试套件时可能会出现问题。

staging/0 |---- Test (Run the tests on the server and displays the output) fired by dependencies.after
staging/0 |------ Test/Phpunit (Run the tests with PHPUnit)
$ cd /var/www/my-deployable-app/releases/20160129220251$ /var/www/my-deployable-app/releases/20160129220251/vendor/bin/phpunit --stop-on-failure
[deploy@staging.mydeployableapp.com] (staging) PHPUnit 4.8.21 by Sebastian Bergmann and contributors.
[deploy@staging.mydeployableapp.com] (staging)
[deploy@staging.mydeployableapp.com] (staging) .
[deploy@staging.mydeployableapp.com] (staging) Time: 4.79 seconds, Memory: 6.00Mb
[deploy@staging.mydeployableapp.com] (staging) OK (1 test, 1 assertion)
[deploy@staging.mydeployableapp.com] (staging)staging/0 |=====> Tests passed successfully

前端构建工具

通常我们的应用程序不仅仅是后端,除非它们是 REST API。使用 Grunt、Gulp 或 Webpack 等工具运行前端构建工具是一项常见任务。使这成为我们部署过程的一部分没有什么比使用钩子来运行以下命令更奇特的了:

'after' => [
    'setup'        => [],
    'deploy'       => [],
    'dependencies' => ['gulp build'],
    'cleanup'      => [],
],

前端通常也依赖于依赖项,因此在安装或更新工具后运行工具。

提示与技巧

运行更新

如果您不想在部署时创建新版本,则可以选择运行更新。执行此操作时请务必小心,因为您将无法回滚到以前的版本,只能回滚到以前的版本。但这是一种使用最新更改更新应用程序的快速而简单的方法:

$ rocketeer update

本地任务

有时,在本地环境中运行任务可能会很好。假设您想要运行 PHPCS 检查或构建静态资产并将它们上传到服务器,从而消除服务器上某些二进制文件的需要。如果您创建任务类,则可以将受保护变量 $local 设置为 true

class MyTask extends Rocketeer\Abstracts\AbstractTask
{
    protected $local = true;

    // [...]
}

结论

部署过程是应用程序生命周期的重要组成部分。像 Rocketeer 这样的工具可以让您轻松地使这成为一件简单的事情。当将它用于 PHP 应用程序时尤其如此,因为它与 PHP 应用程序集成得非常好。

对于那些刚刚开始使用 PHP 或希望通过扩展来扩展您的知识、站点或应用程序的人,我们在 Envato Market 中提供了您可以学习的各种内容。

Rocketeer 입문 튜토리얼을 작성하는 것은 어려운 작업입니다. 이 도구는 너무 유연해서 정지점을 그리는 것이 쉽지 않습니다. 이 도구를 사용할 수 있는 가능성과 이 도구가 귀하와 귀하의 응용 프로그램에 어떤 이점을 줄 수 있는지 이해했기를 바랍니다. 더 자세히 알아보려면 전체 설명서를 읽어 보시기 바랍니다. 이 도구에는 이 기사에서 다룰 수 있는 것보다 훨씬 더 많은 내용이 있습니다.

위 내용은 Rocketeer: PHP 애플리케이션 배포를 위한 최고의 도구의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.