こんにちは。スマートショッピングの@leafと申します。
今回はLaravelを利用してプロジェクトの構築からLaravel/envoyを利用したデプロイ、GitHub Actionsを利用したUnitTestの設定までを行なったのでその話をします。
LaravelとGitHub Actionsは検索してもあまり見つからなかったので、参考にしていただければ幸いです。
LaravelはPHPの人気フレームワークで、フルスタックフレームワークでありながら学習コストが比較的低いところが特徴です。
今年の9月には最新のメジャーバージョンが6になり、アップデートも頻繁に行われているので、今後の発展も期待できると思います。
今回環境を作成するにあたって、初めは全て一から構築することを検討していましたが、Laradockを利用すると簡単に環境を構築することができそうだったので、今回はLaradockを採用することになりました。
LaradockはDocker上で動作するLaravelの開発環境になります。
nginx・MySQLなども含まれているため、これだけで環境を作ることができます。
初めに、Laradockをcloneします。
私の場合は、~/project
以下にLaradockをcloneしました。
$ git clone https://github.com/LaraDock/laradock.git
次にcloneしたディレクトリに移動して設定を変更していきます。
$ cd laradock
$ cp env-example .env
.envファイルを開いてMySQLの設定を変更します。
その他、nginxの設定やPHPのバージョン等もここで変更することができるので、必要に応じて変更を行ってください。
# MYSQL(内容は必要に応じて変更してください。)
MYSQL_VERSION=5.7
MYSQL_DATABASE=smartshopping_management
MYSQL_USER=default
MYSQL_PASSWORD=secret
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=root
ここまで設定ができたら、一度プロジェクトを配置するコンテナを起動します。
※初回起動はなかなか時間がかかります。
$ docker-compose up -d workspace
コンテナが立ち上がったら下記コマンドで接続します。
$ docker-compose exec workspace bash
接続ができたらプロジェクトの作成を行います。
(プロジェクト名(smartshopping-management)は適当なものに置き換えてください。)
※これもライブラリのインストールがあるため長いです。
$ composer create-project laravel/laravel smartshopping-management
プロジェクトが作成できたらworkspaceから出て作業を行います。
$ exit
コンテナも設定変更時、再起動が必要となるので一度止めます。
$ docker-compose stop
現在いるディレクトリの上の階層に、作成したプロジェクトが出来ていることを確認します。
$ ls ../
laradock/ smartshopping-management/
laradoc内の.env
を開いて、APP_CODE_PATH_HOST
を上記で確認したローカルのパスに編集します。
### Paths #################################################
# Point to the path of your applications code on your host
APP_CODE_PATH_HOST=../smartshopping-management
次にプロジェクト内の.env
の設定を変更します。
※ユーザー名とパスワードはここの設定を変更することで切り替えられますが、私が試した時は初回のmigration実行に失敗したので、初回はrootがいいと思います。
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=smartshopping_management
DB_USERNAME=root
DB_PASSWORD=root
これで環境設定はOKです。下記で起動します。
$ docker-compose up -d php-fpm nginx mysql
コンテナが立ち上がったら「http://localhost/ 」にアクセスし、サイトが表示されていることを確認します。
確認ができたら環境構築は完了になります。
実装についてはまたの機会に。。。
今回のデプロイは対象のサーバーも少なく、簡単に作成を行いたかったので、公式パッケージであるenvoyを利用して作成を行いました。
Larval/envoyはリモートサーバーで実行するタスクを、LaravelのViewファイルで利用しているbladeと同様の構文で定義することができるタスクランナーになります。
Laravelでbladeを記述したことがあれば、学習コストがほぼなく、コマンド一つでデプロイが実現できるので、とても便利です。
(ちなみにLaravel以外でも使えます。)
envoyはcomposerでインストールを行うことができるので、下記を対象のプロジェクト配下で実行すれば完了です。
composer require laravel/envoy
envoyのタスクはプロジェクトルートにEnvoy.blade.php
というファイルを作成し、そこに定義を行なっていきます。
今回私が作成したタスクは下記の通りになります。
大体の流れとしては、「ローカルで実行→STGでビルド→本番環境に同期」です。
@servers(['web' => 'ec2-user@192.168.1.1'])
@task('deploy')
// 対象ディレクトリに移動
cd /var/www/html/smartshopping-management
// gitから最新ソースを取得
git pull origin master
// envを本番用に切り替え
cp .env.production .env
// composerでライブラリを更新
composer install
// キャッシュ関連のクリア
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
// マイグレーションの実行
php artisan migrate --force
// npm実行
source ~/.nvm/nvm.sh
nvm use --lts
npm run prod
// 本番環境にビルドしたファイルを同期
rsync -rlOtcv --delete -e ssh /var/www/html/smartshopping-management/ production:/var/www/html/smartshopping-management
@endtask
@finished
@slack('webhookURL', '#deploy', 'デプロイ実行完了')
@endfinished
それでは設定の内容について簡単に解説していきたいと思います。
まず初めのブロックについてですが、ここで対象のサーバーについての情報を設定しています。(カンマ区切りで複数サーバー指定することもできます。)
@servers(['web' => 'ec2-user@192.168.1.1'])
次に定義しているのが実行されるタスクの定義になります。
今回は対象のサーバーが少なかったためタスクをまとめていますが、分割して定義することもできる様なので、気になる方は調べてみてください。
@task('deploy')
// 対象ディレクトリに移動
cd /var/www/html/smartshopping-management
// gitから最新ソースを取得
git pull origin master
// envを本番用に切り替え
cp .env.production .env
// composerでライブラリを更新
composer install
// キャッシュ関連のクリア
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
// マイグレーションの実行
php artisan migrate --force
// npm実行
source ~/.nvm/nvm.sh
nvm use --lts
npm run prod
// 本番環境にビルドしたファイルを同期
rsync -rlOtcv --delete -e ssh /var/www/html/smartshopping-management/ production:/var/www/html/smartshopping-management
@endtask
最後に処理後に実行されるブロックになります。
Slackであれば専用のものが用意されているので、下記の様に設定すればタスク終了時に通知を行うことができます。
@finished
@slack('webhookURL', '#deploy', 'デプロイ実行完了')
@endfinished
実行は対象のディレクトリから下記のコマンドを実行することで動作します。
(最後のdeploy
は作成したタスクの名前で読み替えてください。)
envoy run deploy
これでenvoyを利用したデプロイの設定も完了となります。
envoyは導入やデプロイを比較的簡単に行うことができるので、今後も整備して活用してみたいと思います。
プロジェクト作成後、プルリクにフックさせてUnitTestを実行させる検討を行っていました。
ちょうどその頃にGitHub Actionsが利用できる様になったので、今回はGitHub Actionsを採用することになりました。
GitHubのリポジトリに対するイベントに応じて、タスクを実行できるサービスです。
最近では資料も増えてきており、使いやすくなってきたと思います。
まず初めに定義ファイルを作成していきます。
GitHubにアクセスし、対象のリポジトリのActionsタブを開きます。
今回はいい感じのテンプレートがなかったので、右上のボタンを押して初期定義のみが記載されているファイルを生成します。
この画面で設定を記述していきます。
ファイル名はよしなに変更してあげてください。
下記が今回設定した内容になります。
name: UnitTest
on:
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Copy ENV Laravel Configuration for CI
run: php -r "file_exists('.env') || copy('.env.ci', '.env');"
- name: Install Dependencies (PHP vendors)
run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Create DB and schemas
run: |
mkdir -p database
touch database/database.sqlite
php artisan migrate
- name: Run Test
run: phpunit
それでは設定の内容について簡単に解説していきたいと思います。
最初のname
は名前を定義しているだけなのでよしなに。。。
name: UnitTest
次にon
で始まるブロックですが、ここはトリガーに関する定義を行なっています。
今回であれば、プルリクをトリガーにUnitTestを実行したいので、masterブランチに対してプルリクが作成されたタイミングで実行される様に定義を作成しています。
on:
pull_request:
branches:
- master
最後にjobsのブロックですが、ここは実行する環境とタスクについての定義となります。
runs-on
で指定を行なっているのが実行する環境になります。
steps
でテストを実行するために必要なライブラリの準備を行い、UnitTestを実行しています。
jobs:
build:
runs-on: ubuntu-latest
steps:
# 対象のソースをcheckout
- uses: actions/checkout@v1
# UnitTest用にenvファイルを切り替え
- name: Copy ENV Laravel Configuration for CI
run: php -r "file_exists('.env') || copy('.env.ci', '.env');"
# composerでライブラリの更新
- name: Install Dependencies (PHP vendors)
run: composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
# プロジェクトを動かすためにアプリケーションキーの生成
- name: Generate key
run: php artisan key:generate
# テスト用DBの作成、マイグレーション実行
- name: Create DB and schemas
run: |
mkdir -p database
touch database/database.sqlite
php artisan migrate
# テスト実行
- name: Run Test
run: phpunit
現在、本番環境ではAuroraを利用していますが、IP制限の都合でGitHub Actionsからアクセスを避けたかったので、sqliteをGitHub Actionsのタスクを実行するたびに作成しています。
ci用にenvを切り分けて設定しているのもそのためになります。
# .env.ci
APP_NAME=SmartShopping
APP_ENV=ci
APP_KEY=
APP_DEBUG=true
APP_URL=https://smartshopping
LOG_CHANNEL=stack
DB_CONNECTION=sqlite
DB_DATABASE=database/database.sqlite
ここまで設定をファイルに記載し、プルリクを作成すると、プルリクに実行結果が表示される様になります。
実行のログなどはActionsのタブから確認することができるので、失敗した場合はそちらを確認して対応していくことになります。
これでGitHub Actionsを利用したUnitTestの設定も完了です。
Laravelのプロジェクト立ち上げが初めてということもあり、色々とやり残したこともありますが、なんとか一通り作り上げることができました。
今後は、デプロイとテストのジョブを統合・本番とテスト用のDB統一・本番環境のコンテナ化などを進めていきたいと考えています。
区切りがついた段階でまたブログを書きたいと思いますので、その際はよろしくお願いします。