PHP製のdeployツール"deployer"でLaravelアプリケーションをgit clone/composer installでデプロイ

# deployerとは
deployerとはPHP製のデプロイツールです。
今回はdeploy先でcomposer installをする設定を紹介します。
なお、今回はLaravelで作成したアプリケーションをデプロイします。


# deployerでinstall

```
curl -L -O http://deployer.org/deployer.phar
mv deployer.phar /usr/local/bin/dep
chmod +x /usr/local/bin/dep
```

でインストール完了します。

# 設定ファイル
deployerの設定ファイルを作りたいディレクトリで

```
dep init
```
でdeploy.phpが作られます。なお、
```
dep init laravel
```
でlaravelに特化した設定ファイルが生成できます。

# laravel時の設定
ここではlaravelアプリをdeploy先でcomposer updateさせる設定を紹介します。

```php
<?php
require 'recipe/laravel.php';

// Set configurations
set('repository', '{{各アプリのリポジトリのurl(git~の方}}');
set('shared_files', ['.env']);
set('shared_dirs', [
    'storage/app',
    'storage/framework/cache',
    'storage/framework/sessions',
    'storage/framework/views',
    'storage/logs',
]);
set('writable_dirs', ['bootstrap/cache', 'storage']);

// Configure servers
// リリース先
server('local', '{接続先host or IP}')
    ->user('{{ユーザ名}}')
    ->password('{{パスワード}}')
    ->env('deploy_path', '{{デプロイ先}}');
server('staging', '{接続先host or IP}')
    ->user('{{ユーザ名}}')
    ->password('{{パスワード}}')
    ->env('deploy_path', '{{デプロイ先}}');
```

# deploy
```
dep deploy {deploy対象サーバ}
```
でdeployができるます。
その時のログは以下になります。
```
dep deploy {deploy対象サーバ} -vvvで実行中の詳しいログが表示される) 
```

[19:38:44][root@user /app/laravel-app]# dep deploy local -vv
➤ Executing task deploy:prepare
↳ on [local]
> echo $0
> if [ ! -d /app/user/test2 ]; then mkdir -p /app/user/test2; fi
> if [ ! -L /app/user/test2/current ] && [ -d /app/user/test2/current ]; then echo true; fi
> cd /app/user/test2 && if [ ! -d releases ]; then mkdir releases; fi
> cd /app/user/test2 && if [ ! -d shared ]; then mkdir shared; fi
• done on [local]
✔ Ok [432ms]
➤ Executing task deploy:release
↳ on [local]
> mkdir /app/user/test2/releases/20160425193851
> cd /app/user/test2 && if [ -h release ]; then rm release; fi
> ln -s /app/user/test2/releases/20160425193851 /app/user/test2/release
• done on [local]
✔ Ok [150ms]
➤ Executing task deploy:update_code
↳ on [local]
> which git
> git version
> find /app/user/test2/releases -maxdepth 1 -mindepth 1 -type d
> readlink /app/user/test2/release
> /usr/bin/git clone  --depth 1 --recursive -q git@bitbucket.org:user/laravel-app.git /app/user/test2/releases/20160425193851 2>&1
• done on [local]
✔ Ok [5s 763ms]
➤ Executing task deploy:vendors
↳ on [local]
> if hash composer 2>/dev/null; then echo 'true'; fi
> which composer
> cd /app/user/test2/releases/20160425193851 &&  /usr/local/bin/composer install --no-dev --verbose --prefer-dist --optimize-autoloader --no-progress --no-interaction
• done on [local]
✔ Ok [23s 756ms]
➤ Executing task deploy:shared
↳ on [local]
> if [ -d $(echo /app/user/test2/releases/20160425193851/storage/app) ]; then rm -rf /app/user/test2/releases/20160425193851/storage/app; fi
> mkdir -p /app/user/test2/shared/storage/app
> mkdir -p `dirname /app/user/test2/releases/20160425193851/storage/app`
> ln -nfs /app/user/test2/shared/storage/app /app/user/test2/releases/20160425193851/storage/app
> if [ -d $(echo /app/user/test2/releases/20160425193851/storage/framework/cache) ]; then rm -rf /app/user/test2/releases/20160425193851/storage/framework/cache; fi
> mkdir -p /app/user/test2/shared/storage/framework/cache
> mkdir -p `dirname /app/user/test2/releases/20160425193851/storage/framework/cache`
> ln -nfs /app/user/test2/shared/storage/framework/cache /app/user/test2/releases/20160425193851/storage/framework/cache
> if [ -d $(echo /app/user/test2/releases/20160425193851/storage/framework/sessions) ]; then rm -rf /app/user/test2/releases/20160425193851/storage/framework/sessions; fi
> mkdir -p /app/user/test2/shared/storage/framework/sessions
> mkdir -p `dirname /app/user/test2/releases/20160425193851/storage/framework/sessions`
> ln -nfs /app/user/test2/shared/storage/framework/sessions /app/user/test2/releases/20160425193851/storage/framework/sessions
> if [ -d $(echo /app/user/test2/releases/20160425193851/storage/framework/views) ]; then rm -rf /app/user/test2/releases/20160425193851/storage/framework/views; fi
> mkdir -p /app/user/test2/shared/storage/framework/views
> mkdir -p `dirname /app/user/test2/releases/20160425193851/storage/framework/views`
> ln -nfs /app/user/test2/shared/storage/framework/views /app/user/test2/releases/20160425193851/storage/framework/views
> if [ -d $(echo /app/user/test2/releases/20160425193851/storage/logs) ]; then rm -rf /app/user/test2/releases/20160425193851/storage/logs; fi
> mkdir -p /app/user/test2/shared/storage/logs
> mkdir -p `dirname /app/user/test2/releases/20160425193851/storage/logs`
> ln -nfs /app/user/test2/shared/storage/logs /app/user/test2/releases/20160425193851/storage/logs
> if [ -f $(echo /app/user/test2/releases/20160425193851/.env) ]; then rm -rf /app/user/test2/releases/20160425193851/.env; fi
> if [ ! -d $(echo /app/user/test2/releases/20160425193851/.) ]; then mkdir -p /app/user/test2/releases/20160425193851/.;fi
> mkdir -p /app/user/test2/shared/.
> touch /app/user/test2/shared/.env
> ln -nfs /app/user/test2/shared/.env /app/user/test2/releases/20160425193851/.env
• done on [local]
✔ Ok [1s 260ms]
➤ Executing task deploy:symlink
↳ on [local]
> cd /app/user/test2 && ln -sfn /app/user/test2/releases/20160425193851 current
> cd /app/user/test2 && rm release
• done on [local]
✔ Ok [101ms]
➤ Executing task cleanup
↳ on [local]
> cd /app/user/test2 && if [ -e release ]; then rm release; fi
> cd /app/user/test2 && if [ -h release ]; then rm release; fi
• done on [local]
✔ Ok [100ms]
➤ Executing task success
Successfully deployed!
✔ Ok [0ms]
```

今回local serverのの /app/user/test2/ディレクトリ配下にデプロイしたので、test2ディレクトリは以下のようになっている

```
lrwxrwxrwx 1 user devstaff   45  4月 25 19:39 2016 current -> /app/user/test2/releases/20160425193851
drwxr-xr-x 4 user devstaff 4096  4月 25 19:38 2016 releases
drwxr-xr-x 3 user devstaff 4096  4月 25 19:36 2016 shared
```

sharedは共通の設定ディレクトリ deploy.phpでset('shared_dirs')で設定したディレクトリが入る。

currentはリリースするたびにシンボリックリンクが新しいものに差し代わります

```
lrwxrwxrwx 1 user devstaff   45  4月 25 19:44 2016 current -> /app/user/test2/releases/20160425194344
```

こんな感じで。

デフォルトでは3世代までreleases配下に設置され4世代以降は順次に消される感じです。

#rollback

rollbackは簡単で

```
dep rollback local
```
で行えます。

その時のログは

```
[19:44:18][root@usertest01 /app/laravel-app]# dep rollback local -vv
➤ Executing task rollback
↳ on [local]
> cd /app/user/test2 && find /app/user/test2/releases -maxdepth 1 -mindepth 1 -type d
> cd /app/user/test2 && cd /app/user/test2 && ln -nfs /app/user/test2/releases/20160425193851 current
> cd /app/user/test2 && rm -rf /app/user/test2/releases/20160425194344
Rollback to `20160425193851` release was successful.
• done on [local]
✔ Ok [525ms]

```

1世代前のものに差し代わってることがわかると思います。

# まとめ
deployerはPHPで作られているのでPHPに慣れてる人であればかなり設定が楽にできます。
しかし、今回のようにdeploy先でgit cloneしてcomposer installする方法はかなりdeployに時間がかかります。
基本的に本番環境では行わない方針のほうが良いと思います。

# その他
[ROADMAP](https://github.com/deployphp/deployer)によるとdeployerは4.1でweb-base clientができるらしいです。
ちなみに5/27(金）時点で3.3.0です。