PHP
laravel
Deployer

DeployerでLaravelをデプロイする

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

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

技術選定

Laravel使っているならばLaravel Envoyがあるので、こちらのほうも検討すべし。

導入

色々やりかたある。ここではComposerを使ったやり方です。
公式もチェック

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

$ composer require deployer/deployer

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

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

$ ./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

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は大体こんな感じ

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に

staging.hoge.com
/current -> releases/3
/releases
/shared

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

conf.d
{ProjectRoot}/current/public

適宜webサーバの再起動

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設定がないためデプロイエラーになります。
なので一旦コメントアウト

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

そしてexec

$ ./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ファイルをデプロイする