発生した事象
Laravel sail を使用していたところ、DB接続時に以下のエラーが表示され接続できない事象が発生した。
SQLSTATE[HY000] [1045] Access denied for user 'sail'@' ~
エラー内容を確認するとsail
ユーザーにアクセス権がないようなので、sailユーザーが存在していることやアクセス権周りを確認する。
調査した内容
まず、mysqlコンテナに接続しsail
ユーザが作成されているか確認する。
$ mysql -h 127.0.0.1 -u root -P 3306
mysql> use mysql;
mysql> SELECT User, Host FROM mysql.user;
+------------------+-----------+
| User | Host |
+------------------+-----------+
| root | % |
| healthchecker | localhost |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
ユーザ一覧を確認したところ、sail
ユーザーが作成されていないことが判明。ということは、mysqlイメージ構築時に正常にユーザ等が作成されていないと判断。
イメージ構築時に関連ありそうなdocker-compose.yml
と、同階層の.env
ファイルを確認する。
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'
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=sail
DB_PASSWORD=sercret
Docker Mysqlのドキュメント よりMYSQL_USER
に設定されているユーザがイメージ開始時に、作成されるはずだが、作成されていない。
docker-composeのconfigを確認しても、環境変数は反映されていて問題なさそう。。
$ docker-compose config
mysql:
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_DATABASE: laravel
MYSQL_PASSWORD: sercret
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: sercret
MYSQL_USER: sail
原因
結論からいうと、DBをVolumuesで永続化しているのが原因でした。
なのでdown時に-vオプションを使用してVolumesを削除し、buildし直すことで事象が解消されました。
$ docker-compose down -v
$ docker-compose up -d --build