【Laravel】Sailを使った環境構築

# 前提条件

- Windows環境の場合、WSLを構築しておく必要がある。
- Ubuntuターミナル上でgenie起動

# 環境構築

以下のコマンドを実行する

```bash
$ curl -s "https://laravel.build/{プロジェクト名}?with={使用するサービス（カンマ区切り）}" | bash
```

## 使用するサービスについて

利用可能なサービスは以下になります。

- mysql
- pgsql
- mariadb
- redis
- memcached
- meilisearch
- minio
- selenium
- mailhog

サービスを指定しない場合は

mysql、redis、meilisearch、mailhog、selenium

のサービスが設定されます。

上記コマンドを実行するとlaravelのディレクトリが作成されます。

![スクリーンショット 2023-01-15 18.48.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112812/9e09f59a-c2cd-6f30-d7f9-ae61ebdb266d.png)



docker-compose.ymlの中身は以下の通りになります。

```yaml:docker-compose.yml
# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/8.1
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.1/app
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '81:80'
            - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - pgsql
            - mailhog
    pgsql:
        image: 'postgres:14'
        ports:
            - '${FORWARD_DB_PORT:-5432}:5432'
        environment:
            PGPASSWORD: '${DB_PASSWORD:-secret}'
            POSTGRES_DB: '${DB_DATABASE}'
            POSTGRES_USER: '${DB_USERNAME}'
            POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
        volumes:
            - 'sail-pgsql:/var/lib/postgresql/data'
            - './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
        networks:
            - sail
        healthcheck:
            test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"]
            retries: 3
            timeout: 5s
    mailhog:
        image: 'mailhog/mailhog:latest'
        ports:
            - '${FORWARD_MAILHOG_PORT:-1025}:1025'
            - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
        networks:
            - sail
    minio:
        image: 'minio/minio:latest'
        ports:
            - '9000:9000'
            - '8900:8900'
        environment:
            MINIO_ROOT_USER: '${AWS_S3_ACCESS_KEY_ID}'
            MINIO_ROOT_PASSWORD: '${AWS_S3_SECRET_ACCESS_KEY}'
        volumes:
            - 'sail-minio:/data/minio'
        networks:
            - sail
        command: minio server /data/minio --console-address ":8900"
networks:
    sail:
        driver: bridge
volumes:
    sail-pgsql:
        driver: local
    sail-minio:
        driver: local
```

# Sailの起動

```bash
$ cd {プロジェクト名}
$ ./vendor/bin/sail up -d
```

docker-compose.ymlに記載されたサービスでコンテナが構築されます。

これで環境構築は終わりです。

## （補足）

Sailコマンドを打つのに、毎回「./vendor/bin/sail」コマンドを実行するのは面倒です。

以下のコマンドを実行

```bash
$ alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
```

# Sailコマンドについて

sailコマンドの実態は、「/vendor/laravel/sail/bin/sail」にあります。

例えば、sailコマンドでartisanを使用するには、

```bash:/vendor/laravel/sail/bin/sail
$ sail artisan migrate
```

みたいに記載します。（マイグレーションを実行する）

実際は以下の処理が行われ、sailの後に「artisan」を指定した場合は、

内部で「php aritsan ~」が実行されることがわかります。

また、「ARGS」に実行するコマンドを組み立てていることがわかります。

```shell:/vendor/laravel/sail/bin/sail
# Proxy Artisan commands to the "artisan" binary on the application container...
elif [ "$1" == "artisan" ] || [ "$1" == "art" ]; then
    shift 1

    if [ "$EXEC" == "yes" ]; then
        ARGS+=(exec -u sail)
        [ ! -t 0 ] && ARGS+=(-T)
        ARGS+=("$APP_SERVICE" php artisan "$@")
    else
        sail_is_not_running
    fi
```

「APP_SERVICE」はlaravel.testという値が格納されています。

```shell:/vendor/laravel/sail/bin/sail
export APP_SERVICE=${APP_SERVICE:-"laravel.test"}
```

デフォルトでサービス名が決め打ちされているため、

laravel.testから任意のサービス名に変更した場合は.envファイルのAPP_SERVICE項目も変更しておく必要があります。

組み立てたコマンドは最終行にある以下の処理で実行されます。

```shell:/vendor/laravel/sail/bin/sail
"${DOCKER_COMPOSE[@]}" "${ARGS[@]}"
```

つまり、先ほどの「sail artisan migrate」を実行すると、laravel.testのコンテナ内で「php artisan migrate」を実行するという風に解釈されます。

# まとめ

sailコマンドって何をしているのって思ったら、「/vendor/laravel/sail/bin/sail」を覗くと良いです。

大枠の流れとして、if文で引数を判定して、実行するコマンドを組み立て、最後に実行という流れになってます。


以上

# 参考にさせて頂いたサイト

https://readouble.com/laravel/9.x/ja/installation.html

https://chigusa-web.com/blog/laravel-sail/

https://zenn.dev/ryuu/articles/what-is-sail