はじめに
こんにちは。
この記事は challenge-every-month全員でアウトプット芸人 Advent Calendar 8日目の記事です。
前日の記事は、激アウトプット芸人 の @kdnaktさんの記事です。
4月からGW明けまで異常に忙しく、なかなかブログや挑戦を行えていない僕です。
今回のブログも作業の備忘録的なブログでございます。
Laravelプロジェクトのデプロイをどうしようかと考えていたのですが、Deployerを試してみようと思い、Laravel-Porjectに特化したLaravel-Deployerなるものを発見したのでこちらを使用しました。
Laravel-DeployerはCapistranoと同じくシンボリックリンク型のデプロイツールで、そのデプロイ方法は大きく5つ存在するようです。
- Basic strategy
- First deploy strategy
- Locally-built strategy
- Git pull only strategy (no zero downtime)
- Upload strategy
全部検証しているわけではないのですが、基本的にHostサーバ側で git pullしちゃう形になってるみたいです。
また、.env
や storage
などは sharedに登録されるようですが、 基本的には .env
は .gitignore対象になっていると思うので、 git pullしたあとだと .env
が存在しません。
.env
がない場合は、勝手に空の .env
を作成して sheardFileに登録されます。
それによりもれなくエラーとなります。
このあたり参考サイトをみてても手動で解決しているようでした。
この流れで自分が変えたかったのは、以下です。
- Host側でgit pullしちゃうところ(単純に時間短縮したい)
- ファイルがない場合勝手に
.env
作っちゃう(期待している.env
を作ったり上書きしたりしたい)
こちらを対応するため、先ほど紹介したデプロイ方法をベースにカスタムのデプロイ方法を作りました。
本題
1. インストール
$ composer require lorisleiva/laravel-deployer $ php artisan deploy:init
2. deploy.php修正
今回は自分が変えたかったところを対応するために、 Default deployment strategy
を変更します。
# config/deploy.php <?php declare(strict_types=1); return [ /* |-------------------------------------------------------------------------- | Default deployment strategy |-------------------------------------------------------------------------- | | This option defines which deployment strategy to use by default on all | of your hosts. Laravel Deployer provides some strategies out-of-box | for you to choose from explained in detail in the documentation. | | Supported: 'basic', 'firstdeploy', 'local', 'pull'. | */ 'default' => 'custom',
3. recipeとなるphpファイル修正
基本ベースは upload strategy
をベースにしており、host側で git pullするところを、 git pullせずrsyncを行うように変更しています。
# recipe/custom_strategy.php <?php declare(strict_types=1); namespace Deployer; set('writable_dirs', [ 'bootstrap/cache', 'storage', 'storage/app', 'storage/app/public', 'storage/app/tmp', 'storage/framework', 'storage/framework/cache', 'storage/framework/sessions', 'storage/framework/views', 'storage/logs', ]); desc('Custom Strategy'); task('strategy:custom', [ 'hook:start', 'deploy:prepare', 'deploy:lock', 'deploy:release', 'custom:upload', 'deploy:shared', 'deploy:vendors', 'deploy:writable', 'hook:ready', 'deploy:symlink', 'deploy:unlock', 'cleanup', 'hook:done', ]); set('custom_upload_path', __DIR__ . '/../'); set('custom_upload_vendors', false); set('custom_upload_options', function () { $options = [ '--exclude=.git', '--exclude=.circleci', '--exclude=.env.develop', '--exclude=.env.local', '--exclude=.env.production', '--exclude=.env.staging', '--exclude=.env.testing', '--exclude=server.php', '--exclude=sg.sh', '--exclude=tests', '--exclude=recipe', '--exclude=.editorconfig', '--exclude=.gitattributes', '--exclude=.gitignore', '--exclude=.php_cs.cache', '--exclude=.php_cs.dist', '--exclude=_ide_helper.php', '--exclude=codecov.yml', '--exclude=coverage.xml', '--exclude=phpcs.xml', '--exclude=phpstan.neon.dist', '--exclude=phpunit.xml', '--exclude=readme.md', ]; if (!get('custom_upload_vendors')) { $options[] = '--exclude=/vendor'; } return compact('options'); }); desc('Upload a given folder to your hosts'); task('custom:upload', function (): void { $configs = array_merge_recursive(get('custom_upload_options'), [ 'options' => ['--delete'], ]); upload('{{custom_upload_path}}/', '{{release_path}}', $configs); });
4. デプロイ実行
デプロイ自体は以下のコードで実行できます。
$ php artisan deploy
今回は CircleCIからデプロイするようにしましたので、CircleCI上で checkoutした状態のコードをデプロイします。
このデプロイフローの中で、 .env
の問題も解決させています。
# .circleci/config.yml # デプロイ実行 execute_deployer: steps: - run: cp ~/workspace/.env.production ./.env - run: echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> ./.env - run: echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> ./.env - run: echo "DB_PASSWORD=$DB_PASSWORD" >> ./.env - run: php artisan deploy:run deploy:unlock - run: php artisan deploy -vv
特に変わったことはしておらず、事前に用意している production環境用の .envファイルを .env
ファイルとしてコピーしつつ、デプロイを行うという方法です。
その際に、awsのアクセスキーやシークレットキー・本番DBのパスワードなども環境変数からコピーしています。
deployコマンドを実行する前に deploy:unlock
を実行しているのは、万が一デプロイ中に何かしら失敗した場合に .lockファイルが残っている可能性があり、そのファイルを消さないと次のデプロイが失敗してしまうから、必ず消すようにしています。
5. デプロイ結果
実際のデプロイ結果は以下です。
$ ls -la 合計 412 drwxr-xr-x 10 ec2-user ec2-user 207 4月 26 21:48 . drwxrwxr-x 7 ec2-user ec2-user 55 4月 26 21:46 .. -rw-r--r-- 1 ec2-user ec2-user 1487 4月 26 21:48 .env drwxr-xr-x 10 ec2-user ec2-user 131 4月 26 21:44 app -rwxr-xr-x 1 ec2-user ec2-user 1686 4月 26 21:44 artisan drwxr-xr-x 3 ec2-user ec2-user 34 4月 26 21:44 bootstrap -rw-r--r-- 1 ec2-user ec2-user 2882 4月 26 21:44 composer.json -rw-r--r-- 1 ec2-user ec2-user 400814 4月 26 21:44 composer.lock drwxr-xr-x 2 ec2-user ec2-user 4096 4月 26 21:44 config drwxr-xr-x 4 ec2-user ec2-user 37 4月 26 21:44 database drwxr-xr-x 2 ec2-user ec2-user 40 4月 26 21:44 public drwxr-xr-x 3 ec2-user ec2-user 18 4月 26 21:44 resources drwxr-xr-x 2 ec2-user ec2-user 102 4月 26 21:44 routes lrwxrwxrwx 1 ec2-user ec2-user 20 4月 26 21:46 storage -> ../../shared/storage drwxrwxr-x 51 ec2-user ec2-user 4096 4月 26 21:46 vendor
終わりに
今回はこのような感じです。
このあたりブログに書き留めるために作業中にまとめておきたかったのですが、とにかく忙しく思い出しながら書きました。。。
嗚呼。忙しい。
現場からは以上です。