デプロイツール「Deployer」をつかってみた。PHPerなら簡単に使えます

article-thumbnail

こんにちは、お読みいただきありがとうございます。
Ken(@gootablog)です。

デプロイツール使っていますか?

僕はこれまで使ったことがなく、デプロイ先のサーバーにログインしてgit pullを実行して必要なコマンドを実行してということをしていました。
さすがにこれだと手間が多いし、サーバーを増やしてスケーリングをした時に大変になってくるのでデプロイツールを使ってみることにしました。巷ではRuby製のCapistranoが有名ですが、使っている言語がPHPなので同じ方が良いと思いPHP製のデプロイツール「Deployer」を使ってみました。

デプロイをPHPのコードで管理することができるので、ローカルからコマンドを実行するだけでほとんどのデプロイ処理を行うことができるのでとても便利でした。

備忘録として使い方を書いていきます。

インストール方法

以下のコマンドを実行していくとインストールが完了します。

$ curl -LO https://deployer.org/deployer.phar
$ mv deployer.phar /usr/local/bin/dep
$ chmod +x /usr/local/bin/dep

depと打ってバージョンとコマンドリストが表示されれば完了です。

$ dev

Deployer 6.2.0

プロジェクトの作成

デプロイの設定をしていくためデプロイファイルを作成します。

$ dep init

initと打つとデプロイするプロジェクトを選択するように言われます

 Please select your project type [Common]:
  [0 ] Common
  [1 ] Laravel
  [2 ] Symfony
  [3 ] Yii
  [4 ] Yii2 Basic App
  [5 ] Yii2 Advanced App
  [6 ] Zend Framework
  [7 ] CakePHP
  [8 ] CodeIgniter
  [9 ] Drupal
  [10] TYPO3

LaravelやCakePHPなどのPHPフレームワークが候補に出てきます。
該当するものを選択するとそのフレームワークに適したデプロイファイルが作成されます。

プロジェクトタイプを選択した後、gitのリポジトリと使用ログの収集についての設定を入力する項目が出てきます。リポジトリは後で設定をするのでそのままEnter。使用ログは匿名で開発陣に送信するようですね。送信したくない場合はNoか空白のままEnterを押してください(こちらも後からの設定が可能です)。

上記の設定が終わるとカレントのディレクトリにdeployer.phpというファイルが作成されます。

デプロイの基本的な設定

Commonで作成されたファイルはこんな感じ。

setで値を設定してtaskで処理を実行していきます。

<?php
namespace Deployer;

require 'recipe/common.php';

// Project name
set('application', 'my_project');

// Project repository
set('repository', '');

// [Optional] Allocate tty for git clone. Default value is false.
set('git_tty', true); 

// Shared files/dirs between deploys 
set('shared_files', []);
set('shared_dirs', []);

// Writable dirs by web server 
set('writable_dirs', []);
set('allow_anonymous_stats', false);

// Hosts

host('project.com')
    ->set('deploy_path', '~/{{application}}');    


// Tasks

desc('Deploy your project');
task('deploy', [
    'deploy:info',
    'deploy:prepare',
    'deploy:lock',
    'deploy:release',
    'deploy:update_code',
    'deploy:shared',
    'deploy:writable',
    'deploy:vendors',
    'deploy:clear_paths',
    'deploy:symlink',
    'deploy:unlock',
    'cleanup',
    'success'
]);

// [Optional] If deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');

基本的な設定を見ていきます。

repository

set('repository', '');

ここにgitのリモートリポジトリをセットします。
デフォルトだとmasterのソースコードがプルされます

inventory

inventory('./dir/file.yml');

サーバー情報をymlファイルで管理ができます。
今回サーバーは1つだけですが見やすくするためこちらで分けて書いてます。
複数の環境がある場合は便利そう。

ymlファイルはこんな感じで書きました。

production:
    stage: production
    hostname: hogehoge_production
    user: hoge
    port: hoge
    # configFile: ~/.ssh/config
    identity_file: ~/.ssh/hogehoge
    deploy_path: ~

最初のproductionと書いている部分をdeploy時に指定するとその環境に合わせて反映してくれます。
主にssh接続で使う情報を書いてます。configFileはMacでssh情報を既に書いていると必要ないみたい(ってことはhostname以外もいらなそうだけど試してないです)。deploy_pathは必須ですね。ここで設定したパスがデプロイ時に使用されます。

shared

set('shared_files', ['dir/dir/path.file']);
set('shared_dirs', ['dir/dir',]);

sharedはデプロイをするときに変更してほしくないファイルを設定しておく。そうすることでデプロイをしても変更されないようになる。ログファイル等のアプリケーションで自動で書き込まれたり、ユーザー側で使用されるファイルなどを置くと良さそう。

上の設定だとdeploypath/shared/dir/dir/path.fileという実態のファイルができ、current/dir/dir/path.fileからシンボリックリンクをはる設定になります。

keep_releases

set('keep_releases', 3);

これはデプロイ先にファイルをいくつ残すかという設定。
最新から常にこの数字分のデプロイファイルを保持してくれます。万が一ロールバックしたいというときがあっても安心です。

task

デプロイする際に何らかの処理を加えたい場合はtaskメソッドを使います。
設定したタスクはdep [task_name] [hostname or stage]で実行ができます。

例えばデプロイパスにファイルをアップロードしたい時はuploadを使います

task('config:upload', function(){
    //デプロイパス取得
    $deploy_path = get('deploy_path');

    //upload(ローカルファイル, デプロイ先のパス)
    upload('config/.htaccess', $deploy_path.'/current/html/');
    upload('config/.htpasswd', $deploy_path.'/current/html/');
});

ローカルからcronの設定をする場合はこんな風に書いてみました。
runメソッドでデプロイ先のサーバーでコマンドを実行できます。

task('cron:install', function(){
    $deploy_path = get('deploy_path');
    upload('config/cron', $deploy_path);
    run("sudo /usr/bin/crontab -u [username] $deploy_path/cron");
});

他にもaskConfirmationというメソッドを使うとターミナル上の入力値によって条件分岐で処理を書くことができます。

task('ask', function(){
    if(askConfirmation('Deploy app?'))
    {
        echo 'yes';
    }
    else
    {
        echo 'no';
    }
});

before after

追加したタスクをデプロイする前とか後に実行したい場合はbeforeafterを使います
下の例はdeployタスクが終わった後にconfig:uploadというタスクを実行するように設定しています。

after('deploy', 'config:upload');

デプロイしてみる

後はコマンドを実行するだけです。

$ dep deploy [hostname or stage] -vvv

-vvvと付けると細かい処理をターミナル上に出力してくれるので途中でバグがあっても解決しやすくなります。

ロールバック

デプロイはしたけど前のソースに戻したいとかバグがあってとりあえず1つ戻したい場合ってありますよね。そういう時はrollbackコマンドを使います。

$ dep rollback [hostname or stage]
➤ Executing task rollback
[production] > cd /home/ec2-user && (if [ -d releases ] && [ "$(ls -A releases)" ]; then echo 'true'; fi)
[production] < ssh multiplexing initialization
[production] > cd /home/ec2-user && (cd releases && ls -t -1 -d */)
[production] > cd /home/ec2-user && (if [ -f .dep/releases ]; then echo 'true'; fi)
[production] < true
[production] > cd /home/ec2-user && (tail -n 11 .dep/releases)
[production] > cd /home/ec2-user && (if [[ $(man ln 2>&1 || ln -h 2>&1 || ln --help 2>&1) =~ '--relative' ]]; then echo 'true'; fi)
[production] < true
[production] > cd /home/ec2-user && (cd /home/ec2-user && ln -nfs --relative /home/ec2-user/releases/22 current)
[production] > cd /home/ec2-user && (rm -rf /home/ec2-user/releases/23)
Rollback to `22` release was successful.
• done on [production]
&#x2714; Ok [18s 192ms]

細かいところは消してますがこんな感じで実行されます。
最新のリリースファイルは削除され1つ前のものにリンクが貼られています。

おわり

PHPで書けるのと、書き方が簡単なので使いやすいです。
個人のサービスとか規模が大きくないシステム、サービスならこれで事足りそうですね。

今回は簡単なファイルをアップロードしました。LaravelとかのフレームワークとかComposerを使っているプロジェクトとかだとまた使い心地が違ってくるかもしれません。
今後使ってみて追記なり、記事にしていきます。

ケン(@gootablog)のヒトコト
webアプリ作ってデプロイして公開してみますかね・・・
PHP