Maison > Article > développement back-end > Rocketeer : L'outil ultime pour déployer des applications PHP
Il fut un temps où les développeurs PHP devaient utiliser des outils de déploiement pour les applications Web générales. Vous pouvez le voir, par exemple, dans le tutoriel de Johannes Schickling sur le déploiement d'une application Laravel à l'aide de Capistrano. C'est un outil Ruby et vous devez écrire du code Ruby. Ces outils font le travail, mais ont une intégration limitée avec les applications PHP. Cela peut conduire à de mauvaises solutions pour certains scénarios.
Mais de nos jours, nous avons la chance de disposer d'outils de déploiement écrits dans notre langage qui permettent une intégration plus profonde. Rocketeer est l'un de ces outils, inspiré des frameworks Capistrano et Laravel.
Rocketeer est un outil moderne qui offre une excellente approche de vos besoins de déploiement. Autrement dit, exécutez des tâches et gérez des applications sur différents environnements et serveurs. En plus de cela, il a aussi une certaine magie comme l'installation des dépendances de Composer si un fichier composer.json
est détecté. Pour les applications PHP modernes, vous bénéficiez de paramètres par défaut raisonnables et d'une automatisation des tâches courantes. Et vous pouvez tout personnaliser et étendre.
Vous pouvez le décrire comme un exécuteur de tâches SSH qui s'exécute sur le client. Ces commandes sont exécutées sur le serveur via une connexion SSH. Malheureusement, si vous utilisez un fournisseur d'hébergement partagé qui ne dispose que d'un accès FTP, vous n'avez pas de chance. Vous aurez également besoin d'un référentiel distant à partir duquel l'outil pourra récupérer votre code. Git et SVN sont pris en charge par défaut. Besoin de l'assistance d'un autre système de contrôle de version ? Écrivez votre propre implémentation à l'aide de l'interface fournie.
Vous pouvez installer Rocketeer de deux manières différentes. Vous pouvez télécharger le fichier phar et le rendre exécutable, ou l'installer via Composer. Je suis partisan de ce dernier. L'avoir comme dépendance peut être facilement installé lors du clonage du référentiel. Cela peut profiter à toute personne qui clone le référentiel pour le rendre opérationnel.
Installer à l'aide de Composer :
$ composer require anahkiasen/rocketeer --dev
Je ne vous recommande pas de l’installer globalement. Le conserver au niveau du référentiel garantira que chaque déployeur exécute la même version. Je vous recommande d'utiliser vendor/bin
添加到您的 PATH 中。然后,您可以通过在项目根目录中输入 rocketeer
pour utiliser ce binaire.
Commençons ! Commencez par démarrer les répertoires et les fichiers pour la configuration. Vous pouvez le faire en exécutant rocketeer ignite
dans le répertoire racine du projet.
Lorsque votre application démarre, l'outil crée un dossier .rocketeer
dans votre projet. Le contenu du répertoire ressemblera à ceci :
| .rocketeer | -- config.php | -- hooks.php | -- paths.php | -- remote.php | -- scm.php | -- stages.php | -- strategies.php
Ce sont tous les fichiers de configuration dont vous avez besoin pour commencer à configurer votre déploiement. Chaque fois que je référence un fichier de configuration à partir de maintenant, il existe dans le répertoire .rocketeer/
.
Il est important de comprendre comment Rocketeer gère sa structure de dossiers côté serveur, car c'est un peu différent d'une configuration classique. Il utilise quelques répertoires pour gérer certains aspects du déploiement afin de pouvoir faire son travail efficacement. Vous spécifiez le chemin où vous souhaitez déployer l'application sur le serveur et l'outil s'occupe du reste. Si vous utilisiez /var/www/app
comme répertoire d'application, le dossier ressemblerait à ceci.
| /var/www/app | | -- current => /var/www/app/releases/20160103183754 | | -- releases | | | -- 20160101161243 | | | |-- uploads => /var/www/app/shared/uploads | | | -- 20160103183754 | | | |-- uploads => /var/www/app/shared/uploads | | -- shared | | | -- uploads
Le dossier le plus important est current
, qui pointe vers votre dernière version. C'est ici que la racine du document de votre serveur Web doit être définie. Alors, que se passe-t-il lors du déploiement ?
releases
. current
vers la nouvelle version. Ce processus rend votre déploiement transparent pour les utilisateurs. Le passage d’une version à l’autre est presque instantané et est souvent appelé déploiement atomique.
Certaines données doivent persister entre vos déploiements. Par exemple, il peut s'agir de téléchargements de fichiers, de sessions utilisateur et de journaux. Ces fichiers ou dossiers vont dans le répertoire shared
. L'outil crée des liens symboliques dans chaque version pour la version que vous configurez.
Outil basé sur les événements, toutes les stratégies et tâches sont déclenchées au moment de l'exécution avant et après événements. Ils proposent également un événement spécial pause lorsqu'une tâche échoue. Par exemple, pour un échec général, cela pourrait être dependency.halt
或 deploy.halt
. Cela nous permet d’accrocher les processus là où cela est nécessaire.
Les événements par défaut qui se produisent lors du déploiement sont :
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 的核心,我们发现了一个名为“任务”的概念。幕后发生的大部分事情都是核心任务。任务的定义可以是作为部署中的步骤执行的一组指令。如果我们查看该工具提供的一些类,我们可以大致了解什么是任务:诸如 Deploy
、Setup
、迁移
、 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 中提供了您可以学习的各种内容。
Rédiger un tutoriel d'introduction à Rocketeer est une tâche ardue. L'outil est si flexible qu'il n'est pas facile de tracer un stop. J'espère avoir compris les possibilités d'utilisation de cet outil et comment il peut être bénéfique pour vous et votre application. Si vous souhaitez en savoir plus, je vous recommande de lire la documentation complète. Cet outil offre bien plus que ce que je peux aborder dans cet article.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!