DockerでCakePHP3の環境を作るときにMySQL接続で躓いた話

# 状況
アプリケーション開発初心者の私が@km42428さんの記事を元にDockerでのCakePHP3開発環境を作る際に、自分で作成したDBがCakePHP3に接続できないという問題がありました。

こちらを基に話が進みます⬇︎
[Docker で CakePHP3 実行環境を簡単に構築する (約15分)](https://qiita.com/km42428/items/df1d0a1eefddcf771dfa)

結論から言うとMySQLのユーザーのHostの設定がおかしかった事が原因であるConnection DeniedだったのでDockerとかあまり関係ありませんが、同じことに時間を使ってしまう方が出ないようにと思っております。

# 動作環境
* Docker 18.03.0-ce
* Docker Compose 1.23.2
* vagrant 2.1.2
* centos7

基本的には@km42428さんの記事通りの環境です。今回はホストOSのmacOSにvirtualboxでcentos7を入れ、その中にDockerを構築しています。

記事の内容通りに作成していくと、CacePHP3が動くところまで確認できるはずです。Vagrantfileを編集してポートフォーワーディングをすればホストPCのwebブラウザから見れるはずです。

# MySQLを使ってデータベースを作成、hostコンテナに紐付け

アプリ開発のために自分で新たにデータベースを作成します。

```
#MySQLコンテナのCONTAINER IDを取得
[vagrant@localhost]$ sudo docker ps
[vagrant@localhost]$ sudo docker exec -it [CONTAINER ID] bash
```

以下MySQLの入っているコンテナでDBの作成、ユーザーの作成をします。


```
(以下MySQLコンテナ内)
root@ec5c4d1c03b4:/# mysql -u root -p
Enter password: 

mysql> create database [dbname];
mysql> grant all on [dbname].* to dbuser@% identified by '[yourpassword]';
```

２つ目のSQL文でdbuserという名前のユーザーを作成していますが@の後のhostの部分を"％"（ワイルドカード）にしてあげないといけません。

私はここを`dbuser@localhost`としていました。これだとMySQLコンテナ外からのdbuserとしてのconnectionがdenyされてしまうわけです。

## もしdbuser@localhostだと
```
mysql> SELECT Host, User FROM mysql.user;
+-----------+---------------+
| Host      | User          |
+-----------+---------------+
| %         | my_app        |
| %         | root          |
| localhost | dbuser        |
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
```
my_appは元記事の方で最初に作成されるUserです。そちらを見るとHostが%になっています。このようにUserを作成しないとコンテナ間での接続が出来ないということですね。

## localhostでユーザー作成してしまったら

`RENAME USER hoge TO huga`を使って修正すれば良い。

```
mysql> RENAME USER 'dbuser'@'localhost' TO 'dbuser'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT Host, User FROM mysql.user;
+-----------+---------------+
| Host      | User          |
+-----------+---------------+
| %         | dbuser        |
| %         | my_app        |
| %         | root          |
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
```

dbuserのHostがワイルドカードになりました。

## CakePHP3のapp.phpを変更
アプリケーション内の設定ファイルであるapp.phpのdb接続に関する設定を変更してあげることで、先ほど作成したユーザーで、作成したDBに接続するようにしてあげます。

```php5:config/app.php

#246行目付近
Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'mysql',
            /*
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',
            'username' => 'dbuser', (ここを変更)
            'password' => 'yourpassword',（ここを変更）
            'database' => 'dbname',（ここを変更）
            /*
             * You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6).
             */
            //'encoding' => 'utf8mb4',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,
```

もしくは`$ docker-compose build`をする前にdocker-compose.ymlのMYSQL_USER・MYSQL_PASSWORD・MYSQL_DATABASEを変えてあげれば、ビルドするときにapp.phpがこの変更後のような記述になるはずです。

<img width="796" alt="スクリーンショット 2019-03-17 22.40.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/252750/cb6d0ab9-ab01-8a59-b6c3-163cecb9d912.png">

DataBaseがちゃんと繋がりました。

諸々初心者ですので、技術、表現的に間違いがありましたら、プロフェッショナルな皆様からのご指摘大歓迎でございます。

# 参考
* [Docker で CakePHP3 実行環境を簡単に構築する (約15分)](https://qiita.com/km42428/items/df1d0a1eefddcf771dfa)
* [ユーザーの変更](https://www.dbonline.jp/mysql/user/index3.html)