環境構築からWEBアプリ開発・スマホアプリ開発まで。ときには動画制作やゲームも。

supilog
すぴろぐ

laravelでsailを使って環境構築!DBに接続できない問題の解決(laravel10)

laravelでsailを使って環境構築!DBに接続できない問題の解決(laravel10)

今まであまりsailを使ってこなかったので、使ってメモでも残しておこうと思う。今回はlaravel10で試してます。

curlでインストールする方法はこちら

プロジェクト作成は、公式ドキュメントの「インストール」ページで、どぉーんとcurlによる以下の手順が紹介されています。Docker Desktopがインストールされている状態なら、以下のコマンドで簡単に環境が構築できるようです。

$ curl -s "https://laravel.build/example-app" | bash
-> laravel, mysql, redis, mailpit, meilisearch, seleniumのコンテナが自動生成された

redis, mailpit, meilisearch, seleniumあたりは必要な時にインストールしたい。そんな時は、下記のように指定することも出来るみたい。

$ curl -s "https://laravel.build/example-app?with=mysql,redis" | bash
-> laravel, mysql, redisのコンテナが自動生成された

しかし、プロジェクト作成時に、「with句に何の文字列が使えたっけ?」みたいな手間があるので、個人的にはこちらは使わない。普通にcomposerコマンドで作成したプロジェクトに、sailを導入する流れで実行してみる。

既存のプロジェクトにsailを導入する方法

まずは普通にプロジェクトを作成

$ composer create-project laravel/laravel example-app

sailを導入する

$ cd example-app
$ composer require laravel/sail --dev
$ php artisan sail:install

----------

 Which services would you like to install? [mysql]:
  [0] mysql
  [1] pgsql
  [2] mariadb
  [3] redis
  [4] memcached
  [5] meilisearch
  [6] minio
  [7] mailpit
  [8] selenium
  [9] soketi
 > 0,3
必要なサービスを選んで入力してEnter

起動する

$ ./vendor/bin/sail up


# バックグラウンドで実行したい場合
## 起動
$ ./vendor/bin/sail up -d

## 停止
$ ./vendor/bin/sail down

http://localhost/にアクセスすると、welcomeページが表示できるようになりました。

migrateなどのartisanコマンドは?

sailを使用する場合は、アプリケーションがdockerのコンテナ内で実行されることになるので、artisanコマンドやcomposerコマンドをコンテナ内で実行しなければならないケースが出てきます。

下記のコマンドで、実行することができます。一度コンテナに入って作業する必要はないんですね。ありがたい。

# PHP
$ ./vendor/bin/sail php --version

# artisanコマンド
$ ./vendor/bin/sail artisan migrate

# composerコマンド
$ ./vendor/bin/sail composer require xxxxxxxxxx

ちなみに(laravelの)コンテナに入りたい場合は、以下で入れるみたい。

$ ./vendor/bin/sail shell

しかし、このままartisanコマンドを実行しても失敗します。まさかのDB接続失敗です。えぇぇ・・・。まさかのですよね。実はココというよりDBの設定の話なのですが。

構築自体の話はmigrateが実行できれば終了なので、ここまでです。ここからはDBの注意点について、述べます。

【注意点】「sail:install」によるDB設定書き換えと実際に構築されるモノ

sailを導入する」項目で実行した以下のコマンドがあります。

$ php artisan sail:install

このコマンドで実行される内容の一部を見てみます。

docker-compose.ymlの生成と.envファイルの書き換え

まず.envが自動で書き換えられます。ご覧ください。

# プロジェクト作成時のデフォルト.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

↓

# 「sail:install」によって自動で書き換えられた.env
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=sail
DB_PASSWORD=password

まず「DB_HOST」が書き換えられます。これは、laravelアプリのコンテナからmysqlコンテナに通信しにいこうとするので、問題ないでしょう。

さらに、「DB_USERNAME」「DB_PASSWORD」が修正されています。つまり、開発環境として、この設定で自動でユーザー作成して構築してくれるということ。うんうん、良いでしょう。

さて今度は、自動生成されるdocker-compose.ymlを見てみます。

    mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: '%'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        volumes:
            - 'sail-mysql:/var/lib/mysql'
            - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
        networks:
            - sail

「environment」の項目を見てください。やはり、先程の「DB_USERNAME」「DB_PASSWORD」を使ってユーザー作成するよう自動設定してくれています。加えて言うと、「DB_DATABASE」を使ってDB作成してくれて、rootユーザーのパスワードにも、「DB_PASSWORD」を利用してくれているみたい。

構築さえたDBを確認してみると

コンテナに入ってみます。

$ docker-compose exec mysql bash

bash-4.4# mysql -uroot -p

→.envに書かれたパスワード「password」でログイン可能

さて、DBを閲覧してみます。

mysql> show databases;

+--------------------+
| Database           |
+--------------------+
| example_app        |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testing            |
+--------------------+
6 rows in set (0.00 sec)

分かりますか?.envには、「DB_DATABASE=laravel」と記述してありますが、蓋を開けてみると、作成されていたDBはプロジェクト名である「example_app」でした。

DB名をexample_appにして接続してみると
1) laravelコンテナに入ってmysql接続

$ ./vendor/bin/sail shell

sail@fa8c589225bd:/var/www/html$ mysql -hmysql -usail -p example_app
→無事に接続できました。


2) .envのDB名を書き換えて、migrate実行

$ ./vendor/bin/sail artisan migrate
→無事に実行できました。

【愚痴】おいおい、だとすると!「sail:install」実行時にDB_DATABASEをなぜ書き換えないんだ・・

 いやいやw 「DB_HOST」を書き換えて、「DB_USERNAME」を書き換えて、「DB_PASSWORD」を書き換えて、「DB_DATABASE」だけ書き換えないって・・・なんぞ!

完全にトラップです。

まとめ

sailで構築して開発をスタートできるのは、とても良いですね。ただし、sail使わなくても自分でコンテナ構築できないと、今回のようなトラップになかなか気づけないかもしれないですね。

なんのための自動構築なのか・・・w

ちなみにlaravel9で試してみた

laravel10がまだ浅いから故のバグかな・・と思い、laravel9を試してみました。なんと、laravel9では普通に「laravel」という名前でDBが作成されており、そのまま動作しました。バグかーーい。

それでは。