最小構成で作るDocker&Laravel環境

`compose.yaml` たった1ファイルで作る最小構成のLaravel開発環境を目指します。サクッとLaravelを動かしてみたい人向けです。

## 環境

- PHP: 8.3.7
- Laravel: 11.7.0
- Composer: 2.7.6
- Docker Engine: 25.0.5
- Docker Compose: 2.24.5

※Dockerがインストールされてる前提で進めます。
※2024.5.14時点の最新バージョンを利用しています。

## compose.yaml

```yaml:compose.yaml
services:
  app:
    image: php:8.3-cli-bullseye
    ports:
      - "8000:8000"
    volumes:
      - ./src:/app
    working_dir: /app
    command: php artisan serve --host=0.0.0.0
```

- `services.app` サービス名
- `services.app.image` DockerHubのイメージを指定
  - イメージ名:タグ名
- `services.app.ports` 公開ポートの指定
  - ホスト側:コンテナ側
- `services.app.volumes` バインドボリュームの指定
  - ホスト側:コンテナ側
  - ホスト側のディレクトリをコンテナへマウント
  - ホスト側のエディタで変更した内容が即コンテナ側へ反映
- `services.app.working_dir` コンテナに入った時の作業ディレクトリ
  - バインドマウントしたディレクトリを指定
- `services.app.command` コンテナ起動時に実行するコマンド
  - `docker compose up -d` した時に実行される

## 使い方

### Laravelプロジェクトの作成

```shell-session
$ docker run -v ./src:/app --rm composer:2.7 composer create-project laravel/laravel .
```

※記事執筆時点ではLaravel11.7.0がインストールされます。
※このコマンドについては下のtipsで解説してます。

### Laravelビルトインサーバーの起動

```shell-session
$ docker compose up -d
```

コンテナをデタッチドモード(バックグラウンド)で作成します。

http://localhost:8000

![localhost_8000_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/909aba18-425d-9fd8-6332-f2a35a1e8421.png)

Laravelが動きました！ これで環境構築完了です！

### マイグレーション確認

Laravel11ですとデフォルトのデータベースはSQLiteが指定されています。SQLiteを使う場合は特に設定を追加する必要はありません。

```shell-session
$ docker compose exec app php artisan migrate
$ docker compose exec app php artisan db:seed
```

マイナレーションとシーディングのコマンドが成功すればSQLiteとの疎通できています。

では試しにターミナルからtinkerを起動してユーザーを作成して、一覧表示してみたいと思います。

```shell-session
> App\Models\User::factory()->count(3)->create();

> App\Models\User::all();
= Illuminate\Database\Eloquent\Collection {#5077
    all: [
      App\Models\User {#5075
        id: 1,
        name: "Test User",
        email: "test@example.com",
        email_verified_at: "2024-05-14 06:29:36",
        #password: "$2y$12$sPz2.FO.COMVr.On52yQeeF8qMBC1jDu/aRCJaP7dbU/9C6.JI8VS",
        #remember_token: "bhWDXMk6nQ",
        created_at: "2024-05-14 06:29:36",
        updated_at: "2024-05-14 06:29:36",
      },
      App\Models\User {#5074
        id: 2,
        name: "Lela Brown",
        email: "neil.wehner@example.com",
        email_verified_at: "2024-05-14 06:29:39",
        #password: "$2y$12$Lc6PLgDcFGnwk5F6rUdEc.dbuC9RjyVJVWaV7CcEy/qvGgYO16JCO",
        #remember_token: "uEVWRnOy7a",
        created_at: "2024-05-14 06:29:40",
        updated_at: "2024-05-14 06:29:40",
      },
      App\Models\User {#5073
        id: 3,
        name: "Dr. Baylee Walker DVM",
        email: "satterfield.devin@example.net",
        email_verified_at: "2024-05-14 06:29:40",
        #password: "$2y$12$Lc6PLgDcFGnwk5F6rUdEc.dbuC9RjyVJVWaV7CcEy/qvGgYO16JCO",
        #remember_token: "T5AhfEGgOd",
        created_at: "2024-05-14 06:29:40",
        updated_at: "2024-05-14 06:29:40",
      },
      App\Models\User {#5072
        id: 4,
        name: "Ms. Anne Stroman I",
        email: "mosciski.tressa@example.net",
        email_verified_at: "2024-05-14 06:29:40",
        #password: "$2y$12$Lc6PLgDcFGnwk5F6rUdEc.dbuC9RjyVJVWaV7CcEy/qvGgYO16JCO",
        #remember_token: "5HfkVHVg2y",
        created_at: "2024-05-14 06:29:40",
        updated_at: "2024-05-14 06:29:40",
      },
    ],
  }
```

## tips

### Laravelをインストールした時のコマンドで何してるか

```shell-session
$ docker run -v ./src:/app --rm composer:2.7 composer create-project laravel/laravel .
```

Laravelインストールした時のコマンドについて解説します。

```shell-session
$ docker run \ # Dockerイメージをダウンロード、コンテナ作成、コンテナ実行する
  -v ./src:/app \ # docker run コマンドの --volume オプション。ホスト側のディレクトリをコンテナ側へバインドボリュームする
  --rm \ # docker run コマンドのオプション。コンテナの実行終了と共にコンテナを破棄する
  composer:2.7 \ # docker run コマンドの引数。Dockerイメージを指定する
  composer create-project laravel/laravel . # composer create-project　コマンド。https://github.com/laravel/laravel プロジェクトをダウンロードしてcomposer installする
```

`compose.yaml` にサービスとして登録しても良いですが、`Composer`は常に起動しておく必要がなかったのであえて管理しないようにしています。

※ `compose.yaml`(Docker Composeの設定ファイル) と `Composer`(PHPのパッケージ管理ツール)と名前は似てますが、まったくの別物です。

### composer install したい

```shell-session
$ docker run -v ./src:/app --rm composer:2.7 composer install
```

### appコンテナ内に入ってphpコマンドを実行したい

```shell-session
$ docker compose exec app bash
$ php artisan tinker
```

### データベースの初期化

```shell-session
$ docker compose exec app php artisan migrate:fresh
```

or...

`src/database/database.sqlite` を削除しても大丈夫。

```shell-session
$ rm src/database/database.sqlite
$ docker compose exec app php artisan migrate

   WARN  The SQLite database configured for this application does not exist: database/database.sqlite.

 ┌ Would you like to create it? ────────────────────────────────┐
 │ ● Yes / ○ No  
```

Enter押してYesを選択すると `database.sqlite` ファイルを作成してマイグレーションしてくれる。

### Dockerコンテナの破棄

```shell-session
$ docker compose down
```

### Dockerコンテナ、Dockerイメージの破棄

```shell-session
$ docker compose down --rmi all
```

### ポート番号を変更したい

```yaml:compose.yaml
services:
  app:
    ports:
      - "80:8000"
```

左側の公開ポート番号の設定をするとホスト側の公開ポート番号が設定されます。
`compose.yaml` を変更したらコンテナを再作成する必要があります。

```
$ docker compose up -d --force-recreate
```

- http://localhost でアクセスできる

## ちゃんと作りたい人向け

https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4