🔟

Laravel10時代のプロジェクトの始め方

2023/02/17に公開
2

はじめに

以前、『私的Laravelプロジェクトの始め方』という記事を書いたのですが、あれから2年ほど経過し、いろいろ変わった点があるのでまとめ直しました。

考え方

最近は、MacにPHPがセットアップされていないこともあり、ローカルにPHPをインストールしていなくても始められる手順を実践しています。

セットアップ環境

  • macOS Monterey
  • Docker Desktop v4.9.0
  • Laravel v10.0.3

手順

Laravelインストール & Sailセットアップ

laravel.buildを使ってインストールを行います。これは内部的に、laravelsailのdcockerイメージを呼び出してインストールを行います。使用できるphpのruntimeは7.48.08.18.2です。Laravel10はPHP8.1以上に対応しているので、ここは最新のPHP8.2のruntimeを使用します。

# プロジェクト名はmyprojectとしていますが任意のプロジェクト名でOK
# phpのバージョンを8.1にしたい場合はphp=81
curl -s "https://laravel.build/my-project?php=82" | bash 

インストールの最後にローカル環境のadminのパスワードを要求されるので入力します。

Please provide your password so we can make some final adjustments to your application's permissions.

Password:

なお、上記のコマンドでは以下のリソースが自動でインストールされます。

  • mysql
  • redis
  • meilisearch
  • mailpit
  • selenium

MySQLじゃなくPostgresを使いたい、あるいは必要なリソースだけを指定してインストールしたい場合は、以下のようにwithクエリを使います。

# mysql,redis,mailpitのみインストール
curl -s "https://laravel.build/my-project?php=82&with=mysql,redis,mailpit" | bash 

なお、sailで提供可能なリソースは2023年2月16日時点では以下となります。

[0] mysql
[1] pgsql
[2] mariadb
[3] redis
[4] memcached
[5] meilisearch
[6] minio
[7] mailpit
[8] selenium
[9] soketi

Laravel Sailを起動する

起動する前に.envを開き、使用するポートを追記します。この手順が漏れると、複数のLaravel開発環境を起動したときに、portが競合してしまって起動に失敗します。ダイナミック/プライベートポートは、49513~65535の範囲で割り当てられるので、競合しないようにPORTを割り当ててください。

+#Laravel Sail用のポート割り当て
+APP_PORT=50080
+VITE_PORT=55173
+FORWARD_DB_PORT=53306
+FORWARD_REDIS_PORT=56379
+FORWARD_MAILPIT_PORT=51025
+FORWARD_MAILPIT_DASHBOARD_PORT=58025

また、今回はredisを使うので、CacheとSessionのドライバをfileからredisに変更します。

BROADCAST_DRIVER=log
-CACHE_DRIVER=file
+CACHE_DRIVER=redis
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
-SESSION_DRIVER=file
+SESSION_DRIVER=redis
SESSION_LIFETIME=120

Laravel Sailを起動します。

# バックグラウンドで実行するため、dオプションを使用する
./vendor/bin/sail up -d

すべてのコンテナが正常に起動されているかを確認します。

./vendor/bin/sail ps
NAME                        COMMAND                  SERVICE             STATUS              PORTS
my-project-laravel.test-1   "start-container"        laravel.test        running             0.0.0.0:50080->80/tcp, 0.0.0.0:55173->55173/tcp
my-project-mailpit-1        "/mailpit"               mailpit             running             0.0.0.0:51025->1025/tcp, 0.0.0.0:58025->8025/tcp
my-project-mysql-1          "/entrypoint.sh mysq…"   mysql               running (healthy)   0.0.0.0:53306->3306/tcp
my-project-redis-1          "docker-entrypoint.s…"   redis               running (healthy)   0.0.0.0:56379->6379/tcp

ブラウザからアプリケーションにアクセスします。

最後にsailをailiasとしてzshに登録し、再読み込みしておきましょう。

.zshrc
alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'
source ~/.zshrc

動作/設定内容の確認を行う

開発に必要なコンテナの起動までは完了しましたが、意図したバージョンがインストールされているか、それぞれのコンテナ同士がうまく疎通できているかを確認しておく方が安心できるので、軽く動作確認を行いましょう。

バージョン確認

Laravel9.21から、Laravelの状況を一目で確認できるコマンドが追加されたのでそれを使います。

# artisanはartに省略して実行する
sail art about

以下のような実行結果が表示されます。PHP、Laravel、Composerのバージョンを確認するとともに、各種driverがfileではなくredisになっているか確認します。

MySQLのバージョンも確認します。

sail art db:show

上記コマンドを実行するためにDoctrine DBALをインストールするか尋ねられるのでyesを入力して実行します。

Inspecting database information requires the Doctrine DBAL (doctrine/dbal) package. Would you like to install it? (yes/no) [no]yes

インストール後、再度db:showを実行すると以下の実行結果が表示されます。

各種動作確認を行う

tinkerを起動し、動作確認を実施します。

#tinkerを起動する
sail art tinker

redisを確認する

tinker上で、redisへ読み書きを行います。

> Cache::put('test', 'hoge');
= true

> Cache::get('test');
= "hoge"

> Cache::clear();
= true

mailpitを確認する

tinker上で、テストメールを送信します。

Mail::raw('hello world', fn($msg) => $msg->subject('test')->to('test@example.com'));

mailpitダッシュボードにアクセスしてテストメールをキャッチできたかを確認します。

Laravelの初期設定を行う

日本語を扱う前提なので、それにちなんだ設定と、開発時にEloquentでN+1等を検知できるようにしておきましょう。

app.phpを設定する

config/app.php
//タイムゾーンを日本に変更
-'timezone' => 'UTC',
+'timezone' => 'Asia/Tokyo',

//言語ロケールを日本に変更
-'locale' => 'en',
+'locale' => 'ja',

//Fakerのロケールを日本に変更
-'faker_locale' => 'en_US',
+'faker_locale' => 'ja_JP',

logging.phpを設定する

config/logging.php
//ログを日々ローテーションするように設定する
//これにより14日分のログを日次でファイルに分割して保存する
-'default' => env('LOG_CHANNEL', 'stack'),
+'default' => env('LOG_CHANNEL', 'daily'),

strictモードを設定する

N+1が発生するコードを実行した場合、あるいはModel Attributeの微妙な罠を踏んだ場合に例外がスローされるように設定しておきます。詳細な動作はマニュアルを確認すること。

AppServiceProvider.php
<?php

namespace App\Providers;

+use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
-        //
+        Model::shouldBeStrict(! $this->app->isProduction());
    }
}

Laravel Pintをセットアップする

Laravel9.20から、コードを特定のルールに沿って整形するツールが同梱されるようになリマした。せっかくなので、このツールを使えるようセットアップしましょう。最初から使えるルールには、laravelpsr12があり、 PHPの標準的なコーディング規約であるPSR-12に準拠すべく、psr12をプリセットとして指定します。

# プロジェクトのルートで実行する
echo "{\n\t\"preset\": \"psr12\"\n}" > pint.json

psr12が有効になったかtestモード(ファイル変更は行わない)でチェックします。

sail pint --test

プルリクの対象となるコードだけに適用する場合は以下のオプションをつけて実行します。

sail pint --dirty

.env暗号化

Laravel9.32から、.envを暗号化してリポジトリにコミットできます。元々、.envは機密性の高い値(APIキーやDBのパスワード等)を扱うものであったため、リポジトリの追跡対象外となっていました。しかしそのせいで.envの最新の状態が分からなくなり、チーム開発時に困った事態になるともしばしばあったと思います。このため、ローカル環境用の.envに限り本仕組みを活用し同期できるようにしたいと思います。

ファイルの暗号化

以下のコマンドで暗号化すると、.env.encryptedというファイルが生成されるので、それをリポジトリにコミットします。欠点としてローカルの.envに手を加えるたびに暗号化してコミットする必要があります。

sail art env:encrypt --force

ファイルの復号

sail art env:decrypt --key=xxxx --force

開発に役立つパッケージをインストールする

開発に役立つパッケージとして以下をインストールします。laravel-telescopeやlaravel-ide-helperも人気ですが、この辺りは人それぞれだと思うので除外。

barryvdh/laravel-debugbar

Laravelのデバッグに必要な情報を出力してくれるパッケージ。実行されるSQL、作成されるModelオブジェクト、セッションの中身等を確認できます。

sail composer require barryvdh/laravel-debugbar --dev

おわりに

Laravelはバージョン8以降、毎週何らかの機能追加を行なっており、マイナーバージョンアップで予想外の変更が加わることもあります。このため、Laravel9が出た当初と比べても、 Laravelセットアップ後に行うべき手順は大きく変わっているのが実情です。この機会にぜひ一度差分を埋めてみてください!

Discussion

kawaxkawax

新規プロジェクト作成は

curl -s "https://laravel.build/example-app" | bash

laravelsail/php82-composerを使うのは「既存のプロジェクトをDockerしかない環境でインストールするため」
git clone後、sailを使うには先にcomposer installが必要だけどphpもcomposerもないからできない。
こういう場面でのみ仕方なく使う。

docker run --rm \
    -u "$(id -u):$(id -g)" \
    -v "$(pwd):/var/www/html" \
    -w /var/www/html \
    laravelsail/php82-composer:latest \
    composer install --ignore-platform-reqs

laravel.buildでもやってることはほとんど同じだけどdockerコマンドを長々と書くよりlaravel.build一つで終わらせるのがLaravelの使い方。
https://github.com/laravel/sail-server/blob/master/resources/scripts/php.sh

imahimah

ご指摘ありがとうございます。

curl -s "https://laravel.build/example-app" | bash はphpのバージョンを指定できない、意図しないリソースがインストール(mysql,redis,maillisearch,mailpit,selenium)されてしまうと勘違いしていたので、その内部スクリプトを参考にしてランタイムとリソースを指定できるよう手順を書いていました。ご提示いただいたスクリプトを拝見してバージョン指定、リソース指定ができることを理解したので修正しました。教えてくださり大変助かりました。