📝

Laravel sailを使ったDocker環境でのWebアプリケーション開発環境設定

に公開

https://readouble.com/laravel/11.x/ja/sail.html

この辺のドキュメントを見ても微妙にわかり辛いのかなと思った為、というのと、時々見かけるドキュメントでdocker-composeで自力で用意するくらいのがあって、それをするならこれの方が楽なんじゃないかなと思った為書いておく。

必要なもの

  • docker-compose
  • git(optional)

EC2で動作させてみる場合はsmall以上のサイズを推奨。

larave.buildから引き込んでくる

curl -s "https://laravel.build/example_app?with=mysql" | bash

このように何かしらDBエンジンを付けて持ってくる。各種選択できるのであるが調べるの面倒ならハンズオン的にこの通りに入力しよう。


実行例

gitへの登録

実はlaravel.buildで構築したものは .env が既に設置してあったり諸々ある程度サービス起動の準備が整っているのであるが、gitに登録する場合 .gitignore により、これらのリソースがpushされずcloneしたら動かないという事がある。従ってこの段階で一度御自身のgitリポジトリーに登録しておくのがよい

というわけで、laravel.buildから構築してpushしただけのものを以下に置いた

https://github.com/catatsumuri/laravel-inertia-stack-ja/tags

これを利用する場合の作業例

rm -rf example_app
wget https://github.com/catatsumuri/laravel-inertia-stack-ja/archive/refs/tags/laravel-initial-setup.tar.gz
tar xvzf laravel-initial-setup.tar.gz    
cd laravel-inertia-stack-ja-laravel-initial-setup/   

必要に応じて御自身のリポジトリに再配置したりなどすると良いかもしれない。

composer

gitからcloneした場合、通常 vendor/ は含まれていないはずだ。

従ってcomposerを使ってライブラリーを引きこむ必要がある。dockerを使う場合は以下のようにしてこれをinstallするのが楽なのでは無いかと思われる。

docker run --rm -v $(pwd):/app composer install

.envの作成

.env というのは単純に環境変数の定義ファイルであるが、通常、雛形 .env.example から作成する事が多いだろう。

cp .env.example .env

このようにする。

DBの設定

ここで、.env の内容のDBの初期状態の項目を見ると

DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=

このようになっている。laravel sailの場合DBエンジンが付いてくる事が多いので、そちらに合わせこんでおく。ここではmysqlを使っているため、以下のように書き換える

#DB_CONNECTION=sqlite
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=sail
DB_PASSWORD=password

sailの起動

この状態で ./vendor/bin/sail up/ するのであるが、これを行うと端末が奪われてしまう。 -d オプションを付けてもいいが、安定するまでエラーが出ると面倒なので複数端末を使うなり、gnu screenのようなツールを使うなりして何とか2つ端末を確保してみよう。


ここではGUIのターミナルで2つタブを用意して、1つをsailの起動に当てている

DBの初期化

以下のようにして行う

./vendor/bin/sail artisan migrate:fresh --seed

このように、artisanコマンドは ./vendor/bin/sail artisanのようにして起動する。


laravelのバージョン

ポートを変更したいとき

これはdocker-compose.ymlに諸設定があって

docker-compose.yml
services:
    laravel.test:
        build:
            context: './vendor/laravel/sail/runtimes/8.4'
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: 'sail-8.4/app'
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
            - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
# <snip...>

このようになっている

- '${APP_PORT:-80}:80'

基本的に

マップ先:マップ元

なのだが、シェル構文${APP_PORT:-80}により、環境変数APP_PORTが利用されているときはそれを使い、そうでなければ80を使うという設定が為されている。つまりポート8000で起動したい等の場合は .env

APP_PORT=8000

などを書き込んでおくとそのポートで起動する。


エラーになっているものの、ポート8000で起動した例

アプリケーションキー

初期設定では必ず行うものであるが、以下のartisanコマンドで行う事になる

./vendor/bin/sail artisan key:generate

以上でdefaultページが起動するはずだ


起動したdefaultページ

sailが起動してから確認する事

artisanの使い方

既に見てきたように artisan

 ./vendor/bin/sail artisan

で起動する

mysqlシェルへの入りかた

./vendor/bin/sail mysql

で行う。

mysqlの時刻設定について

以降はmysqlの設定

APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
#APP_TIMEZONE=UTC
APP_TIMEZONE=Asia/Tokyo
APP_URL=http://localhost

このようにした場合、少なくともdockerコンテナのmysqlはシステムの時間で保存しにいくのでちょっとあやしくなる


JSTで保存されている

この時に

config/database.php
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DB_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'laravel'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => env('DB_CHARSET', 'utf8mb4'),
            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
            'timezone' => '+09:00', // これ
        ],

を付けておくと


UTCで保存されたtimestampをlaravelがJSTに変換している

テスト用のDBを確認しておく

testingというデータベースの項目が見える


これはどこで生成されているかというと

docker-compose.yml
        volumes:
            - 'sail-mysql:/var/lib/mysql'
            - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'

この辺のシェルスクリプトがやっているが、内容は深掘りしなくていいので

phpunit.xml
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="APP_MAINTENANCE_DRIVER" value="file"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_STORE" value="array"/>
        <env name="DB_DATABASE" value="testing"/>
        <env name="MAIL_MAILER" value="array"/>
        <env name="PULSE_ENABLED" value="false"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="TELESCOPE_ENABLED" value="false"/>
    </php>

ここでの

<env name="DB_DATABASE" value="testing"/>

この項目でテストにおいてこのDB_DATABASEが使われるという事。

テストの実行

上記の設定により特に何も考えずとも

./vendor/bin/sail test

でテストが実行できる

この環境をワンタッチで行ってくれるのがsailの便利な所だろう

サービスの追加

これは artisan sailで行う

 sail
  sail:add                  Add a service to an existing Sail installation
  sail:install              Install Laravel Sail's default Docker Compose file
  sail:publish              Publish the Laravel Sail Docker files
./vendor/bin/sail artisan sail:add

とするとインタラクティブに聞いてくる

ここで追加できるものに関しては後日書くかもしれないし書かないかも。

追加のライブラリー

  • Composer コマンド:

    • sail composer ... : Composer コマンドを実行
      • sail composer require laravel/sanctum : Laravel Sanctum をインストール
  • Node コマンド:

    • sail node ... : Node.js コマンドを実行
      • sail node --version : Node.js のバージョンを表示
  • NPM コマンド:

    • sail npm ... : npm コマンドを実行
    • sail npx : npx コマンドを実行
      • sail npm run prod : prod スクリプトを実行
  • PNPM コマンド:

    • sail pnpm ... : pnpm コマンドを実行
    • sail pnpx : pnpx コマンドを実行
      • sail pnpm run prod : prod スクリプトを実行
  • Yarn コマンド:

    • sail yarn ... : Yarn コマンドを実行
      • sail yarn run prod : prod スクリプトを実行
  • Bun コマンド:

    • sail bun ... : Bun コマンドを実行
    • sail bunx : bunx コマンドを実行
      • sail bun run prod : prod スクリプトを実行

devContainer

実はlaravel.buildには

ってオプションがあるので

curl -s "https://laravel.build/example-app?with=mysql&devcontainer" | bash

とするとjsonが生成される。これは

でも生成できる。いずれにしても

.devcontainer/devcontainer.json
// https://aka.ms/devcontainer.json
{
        "name": "Existing Docker Compose (Extend)",
        "dockerComposeFile": [
                "../docker-compose.yml"
        ],
        "service": "laravel.test",
        "workspaceFolder": "/var/www/html",
        "customizations": {
                "vscode": {
                        "extensions": [
                                // "mikestead.dotenv",
                                // "amiralizadeh9480.laravel-extra-intellisense",
                                // "ryannaddy.laravel-artisan",
                                // "onecentlin.laravel5-snippets",
                                // "onecentlin.laravel-blade"
                        ],
                        "settings": {}
                }
        },
        "remoteUser": "sail",
        "postCreateCommand": "chown -R 1000:1000 /var/www/html 2>/dev/null || true"
        // "forwardPorts": [],
        // "runServices": [],
        // "shutdownAction": "none",
}

このようなjson的なファイルが出来るだけなので、これをコピーしてもいい。
vscodeでやる時は置いておくとある程度は便利なはず。

Discussion