atijust's blog

技術的なこととか。

Rocketeerを本格的に使うのに必要なちょっと進んだ機能

PHPのためのCapistrano風デプロイツール「Rocketeer」でLaravelをデプロイするの補足として、Rocketeerを本格的に運用する上で必要となってくるちょっと進んだ機能を紹介します。

複数のリモートホストを一括で操作する

app/config/packages/anahkiasen/rocketeer/config.phpconnectionsには複数のリモートホストの接続情報を設定することができます。

app/config/packages/anahkiasen/rocketeer/config.php

// The various connections you defined
// You can leave all of this empty or remove it entirely if you don't want
// to track files with credentials : Rocketeer will prompt you for your credentials
// and store them locally
'connections' => array(
    'sv1' => array(
        'host'      => '203.0.113.1',
        'username'  => 'hogehoge',
        'password'  => '',
        'key'       => '/Users/hogehoge/.ssh/id_rsa',
        'keyphrase' => '',
    ),
    'sv2' => array(
        'host'      => '203.0.113.2',
        'username'  => 'hogehoge',
        'password'  => '',
        'key'       => '/Users/hogehoge/.ssh/id_rsa',
        'keyphrase' => '',
    ),
),

各コマンドは--onオプションで操作対象のリモートホストを指定できます。

$ ./artisan deploy:deploy --on sv1
$ ./artisan deploy:rollback --on sv1

カンマ区切りで複数指定も可能です。

$ ./artisan deploy:deploy --on sv1,sv2
$ ./artisan deploy:rollback --on sv1,sv2

これで複数のリモートホストを一括して操作できますね。

ただ、毎回--onオプションを指定するのも面倒なので、そんなときはデフォルトで使用する接続情報を設定してやりましょう。 --onオプションが指定されないときは、defaultに設定した接続情報が使われます。

app/config/packages/anahkiasen/rocketeer/config.php

// The default remote connection(s) to execute tasks on
'default' => array(
    'sv1',
    'sv2',
),

こうしておけば--onオプションが指定されていないときは自動的sv1sv2の両方が操作対象になります。

$ ./artisan deploy:deploy

複数のリモートホストを扱う上で注意すべき点としては、リモートホストごとにリリースのタイムスタンプが変わるということでしょうか。

あと、Capistranoと違ってタスクは直列で実行されます。リモートホストの台数が多いと少し時間がかかってしまうかもしれません。

リモートホストごとにデプロイの設定を変える

本番とステージングでデプロイするブランチを変えたい、といった時はどうすればよいでしょうか。

例えば、productionstagingの2つのリモートホストがあって、productionではmasterブランチを、stagingではdevelopブランチをデプロイしたいとします。

そんなときは、app/config/packages/anahkiasen/rocketeer/config.phpon.connectionsでグローバルな設定値を上書きすればOKです。

app/config/packages/anahkiasen/rocketeer/config.php

// Contextual options
//
// In this section you can fine-tune the above configuration according
// to the stage or connection currently in use.
// Per example :
// 'stages' => array(
//  'staging' => array(
//      'scm' => array('branch' => 'staging'),
//  ),
//  'production' => array(
//    'scm' => array('branch' => 'master'),
//  ),
// ),
////////////////////////////////////////////////////////////////////

'on' => array(

    // Connections configuration
    'connections' => array(
        'production' => array(
            'scm' => array('branch' => 'master'),
        ),
        'staging' => array(
            'scm' => array('branch' => 'develop'),
        ),        
    ),

),

こうしておけば、productionを操作するときはscm.branchmasterstagingを操作するときはscm.branchdevelopに設定されます。scm.branchだけでなく、他の設定も上書きすることができますので、色々便利に使えそうですね。

1つのリモートホストに複数のリリースを同居させる

リモートホストを1台しか用意できないなんて場合は、本番用のリモートホストに動作確認用のステージング環境も同居させてしまいたい、なんていうことがあるかもしれません。

そんな場合はディレクトリを分けて1つのリモートホストに複数のリリースを同居させてしまいましょう。

app/config/packages/anahkiasen/rocketeer/stages.php

// Stages
//
// The multiples stages of your application
// if you don't know what this does, then you don't need it
//////////////////////////////////////////////////////////////////////

// Adding entries to this array will split the remote folder in stages
// Like /var/www/yourapp/staging and /var/www/yourapp/production
'stages' => array('production', 'staging'),

このように設定しておけば、

$ ./artisan deploy:deploy --stage production

とすれば/var/www/rocketeer-example/productionに、

$ ./artisan deploy:deploy --stage staging

とすれば/var/www/rocketeer-example/stagingにデプロイされます。

--stageオプションを省略したときのデフォルトを設定することもできます

app/config/packages/anahkiasen/rocketeer/stages.php

// The default stage to execute tasks on when --stage is not provided
'default' => 'production',

デフォルトが設定されてない状態で--stageオプションを省略するとproductionstaging両方がデプロイされてしまうので注意。

ステージ毎に設定を変更することもできます。

app/config/packages/anahkiasen/rocketeer/config.php

'on' => array(

    // Stages configurations
    'stages' => array(
        'production' => array(
            'scm' => array('branch' => 'master'),
        ),
        'staging' => array(
            'scm' => array('branch' => 'develop'),
        ),
    ),
),

これでproductionにはmasterブランチが、stagingにはdevelopブランチがデプロイされるようになります。

以上、Rocketeerを本格的に運用する上で必要なちょっと進んだ機能を紹介しました。他にもタスクをフックしてユーザ定義の処理を差し込んだり、オリジナルのタスクを書いたり、プラグインだったりといった楽しそうなトピックがありますが、まだ自分は使ったこと無いし、その辺の情報は公式ドキュメントが充実しているので、そちらを参照ください( 英語だけどコードを多用した説明なのでエンジニアならなんとかなるハズ)。