DeployerでLaravelをデプロイする


PHPのデプロイの自動化。RailsとかだとCapistranoさんがおなじみ。
最近はLaravel Recipeをrequireするようになったようです。

ちょっと詰まったのでメモ。

## 技術選定

Laravel使っているならば[Laravel Envoy](https://github.com/laravel/envoy)があるので、こちらのほうも検討すべし。

## 導入

色々やりかたある。ここではComposerを使ったやり方です。
[公式](https://deployer.org/)もチェック

LaravelだとComposer使っているだろうし、プロジェクトルート直下でインストール

```bash:
$ composer require deployer/deployer
```

これで`vendor/bin/dep`コマンドが使えます。

それでは、configを作りましょう。プロジェクトルートで

```bash:
$ ./vendor/bin/dep init
```

```
  Welcome to the Deployer config generator  
 This utility will walk you through creating a deploy.php file.
 It only covers the most common items, and tries to guess sensible defaults.
 Press ^C at any time to quit.
 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
```
職人さんは1番です。
あとは、リポジトリ設定とか。httpsでgitしてた人はここでsshを検討してもいいかも。httpsだと毎回IDとPassを求められてしまうので。
sshならばデプロイするサーバも公開鍵をgithubなりbitbucketなりしっかりと登録すること。後のgit cloneでエラーになります。

`deploy.php`ができるはずです。
最近のバージョンだとファイル行頭の`require 'recipe/laravel.php'`でLaravelのレシピを読み込んでるのでほとんどなんでもしなくてOK

```php:deploy.php
// Project name
set('application', env('APP_NAME'));

// Shared files/dirs between deploys
add('shared_files', ['.env']);
add('shared_dirs', [
    'storage',
]);

// Writable dirs by web server 
add('writable_dirs', ['bootstrap/cache', 'storage']);
```
アプリケーション名ですが、Laravelのconfig.appと同じように`env('APP_NAME')`でいいでしょう。

AWSで、stagingだとhostは大体こんな感じ

```php:deploy.php
host('staging.hoge.com')
    ->stage('staging')
    ->user('ec2-user')
    ->port('22')
    ->identityFile('~/.ssh/秘密鍵ファイル名.pem')
    ->set('deploy_path', '/var/www/staging.hoge.com');
```

PATHに関しては、だいたいPermissonが許されればdirを作ってくれます。
この場合だと、デプロイ成功するとdeploy_pathに

```bash:staging.hoge.com
/current -> releases/3
/releases
/shared
```

こんな感じの構成。currentが最新のorigin.masterブランチが入る。
nginxなりApacheのdocument_rootを`{ProjectRoot}/current/public`に変更

```bash:conf.d
{ProjectRoot}/current/public
```

適宜webサーバの再起動

```bash:nginxの例
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo service nginx restart
```



## デプロイ
まず最初にこのままdeployすると失敗します(ハマりポインツ)

Laravelは.envをgitignoreするのがデフォルトです。
ローカル(ホスト)側からコピーするようになってないので、まず最初はmigrateせずデプロイを通す必要があります。

deployerの初期設定だと、`.env`がないと空の`.env`を作ります。`deploy.php`では、symlink前にmigrateが走るので、DB設定がないためデプロイエラーになります。
なので一旦コメントアウト

```php:deploy.php
//before('deploy:symlink', 'artisan:migrate');
```

そしてexec

```bash:
$ ./vendor/bin/dep deploy staging
✈︎ Deploying master on staging.hoge.jp
✔ Executing task deploy:prepare
✔ Executing task deploy:lock
✔ Executing task deploy:release
✔ Executing task deploy:update_code
✔ Executing task deploy:shared
✔ Executing task deploy:vendors
✔ Executing task deploy:writable
✔ Executing task artisan:storage:link
✔ Executing task artisan:view:clear
✔ Executing task artisan:cache:clear
✔ Executing task artisan:config:cache
✔ Executing task artisan:optimize
✔ Executing task deploy:symlink
✔ Executing task deploy:unlock
✔ Executing task cleanup
Successfully deployed!
```

はい、`.env`が空のままデプロイが完了しました。

このままだと`.env`がないため、アプリケーションが動きません。
サーバにsshでログインして`/{deploy_path}/shared/.env`が空なので、実際の`.env`を書き換えましょう。

`・{deploy_path}/current/.env`がこれにシンボリックリンクを貼っているのでこれで完了です。


## See also
もし、環境ごとに.envを分けて頻繁にデプロイする場合はこちらの方法も。
[Deployerを使ってLaravelのenvファイルをデプロイする]
(https://qiita.com/myoshioka/items/925d3c084d7971c03e81)