こんにちは、お読みいただきありがとうございます。
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
は必須ですね。ここで設定したパスがデプロイ時に使用されます。
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
追加したタスクをデプロイする前とか後に実行したい場合はbefore
かafter
を使います
下の例は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を使っているプロジェクトとかだとまた使い心地が違ってくるかもしれません。
今後使ってみて追記なり、記事にしていきます。