未だにHyper-V+DockerのPHP開発環境が落ち着かない。
今度はDockerコンテナ化したMariaDBに、諸々のアプリからアクセス出来ない問題が勃発したので、その試行錯誤工程をまとめました。
追記2018/02/03
PCが変わったのを機にもう一度やってみたら あっさり出来ました。
改めてやった時の備忘録はこちら。
ベストプラクティスかは分かりませんが、当記事のよりは洗練されたかと。
DockerのMySQLコンテナに外部からアクセスする方法まとめ改 - Qiita
環境
- Windows10 Proffesional
- Hyper-V
- Docker for Windows
何がMariaDBに繋がらない?
- A5:SQL mk-2
- CakePHP2
やってみると対処法が違いました。
現状の構成
現状docker-compose.ymlに記載している内容は以下の通りです。
version: '2'
services:
mariadb:
container_name: mariadb
image: mariadb:user
ports:
- '3306:3306'
volumes:
- db:/var/lib/mysql
privileged: true
command: /sbin/init
php_app:
container_name: php_app
image: php7:user
expose:
- '9000'
ports:
- '8080:80'
volumes:
- ../app_dir/:/var/www/html
depends_on:
- mariadb
privileged: true
command: /sbin/init
volumes:
db:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2814f7b46798 php7:user "/sbin/init" 5 days ago Up 3 hours 9000/tcp, 0.0.0.0:8080->80/tcp php_app
c376bb48006c mariadb:user "/sbin/init" 5 days ago Up 3 hours 0.0.0.0:3306->3306/tcp mariadb
- mariadb:user
公式のcentosコンテナ(CentOS7)にMariaDBを手動インストールしたもの。
単純にUbuntuに慣れていないのと、クエリログの設定を予めしておきたかったので自作。 - php7:user
これも公式centosコンテナにPHP7.1とXDebugを手動インストールしたもの。
同じくUbuntuに慣れていないのと、XDebugの設定を予めしておきたかったので自作。
A5:SQLが繋がらない!
エラー内容
「#28000Access denied for user 'root'@'gateway' (using password: NO)」
ホスト名: localhost
(ポート: 3306)
ユーザー名: root
パスワード無し。
docker execしたコンソール上からのログインは可能。
試行錯誤
どうやら外部アクセス関連の設定が怪しい。
MariaDB [mysql]> SELECT `Host`, `User`, `Password` FROM user;
+--------------+------+-------------------------------------------+
| Host | User | Password |
+--------------+------+-------------------------------------------+
| localhost | root | |
| 2814f7b46798 | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | | |
| 2814f7b46798 | | |
+--------------+------+-------------------------------------------+
6 rows in set (0.00 sec)
※「2814f7b46798」はphp_appコンテナのコンテナIDです。
ここから読み取る限り、このMariaDBにアクセス出来るホストは「localhost」「127.0.0.1」「php_app」コンテナの3つ。
「::1」は、
sh-4.2# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
とのことで、恐らく「localhost」と同義。
エラーメッセージ見る限り、「gateway」からのアクセス扱いになっているようで、それじゃあアクセス出来ませんね。
ユーザー作成
というわけでアクセス出来るユーザーを作ります。
MariaDB [(none)]> USE mysql;
Database changed
-- a5m2ユーザーを、gatewayからのアクセス用ユーザーとして作成
MariaDB [mysql]> CREATE USER a5m2@gateway IDENTIFIED BY 'a5m2';
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> SELECT `Host`, `User`, `Password` FROM user;
+--------------+------+-------------------------------------------+
| Host | User | Password |
+--------------+------+-------------------------------------------+
| localhost | root | |
| 2814f7b46798 | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | | |
| 2814f7b46798 | | |
| gateway | a5m2 | *7367A95690040CB321E09B233CC56FCCB6AB2E0A |
+--------------+------+-------------------------------------------+
7 rows in set (0.00 sec)
-- a5m2ユーザーに全権限を設定
MariaDB [mysql]> GRANT ALL PRIVILEGES ON *.* TO a5m2@gateway WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
Hostは「%」(Hostが何でも可)でも良いのですが、つまりは誰でもアクセス可になってしまいます。
いくらローカル環境とはいえ、ちょっと良くない上、今回はHostがちゃんと分かっているので指定しました。
改めてA5:SQLの設定をします。
ホスト名: localhost
(ポート: 3306)
ユーザー名: a5m2
パスワード: a5m2
これでA5SQLから繋がりました。一件落着。
原因
Windowsからのアクセスはlocalhostではなく外部ホスト扱いになるらしく、そのホストからの接続設定がされていなかった。
よって、Windowsからのアクセス用ユーザーを作って解決。
CakePHP2からも繋がらない!
ヘーイ!今度は何デスカー!?
エラー内容
Database connection "Mysql" is missing, or could not be created.
SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'database',
'prefix' => '',
'encoding' => 'utf8',
);
A5:SQLが繋がったと思ったら今度はCakePHP2からエラーが。
まーたlocalhostじゃ繋がらないのか。。
試行錯誤
一旦「host」をループバックアドレスである127.0.0.1
にしてみます。
Database connection "Mysql" is missing, or could not be created.
SQLSTATE[HY000] [2003] Can't connect to MySQL server on '127.0.0.1' (111)
状況変わらず。
Dockerで別コンテナにする=別ホストでDBが動いている、ということなのでしょうか。
MariaDB [mysql]> SELECT `Host`, `User`, `Password` FROM user;
+--------------+------+-------------------------------------------+
| Host | User | Password |
+--------------+------+-------------------------------------------+
| localhost | root | |
| 2814f7b46798 | root | |
| 127.0.0.1 | root | |
| ::1 | root | |
| localhost | | |
| 2814f7b46798 | | |
| gateway | a5m2 | *7367A95690040CB321E09B233CC56FCCB6AB2E0A |
+--------------+------+-------------------------------------------+
7 rows in set (0.00 sec)
とはいえ、コンテナIDがちゃんとmysql.userテーブルにもあるので、繋がりそうなものですが、繋がらないのは何故なんでしょうね。
接続先の変更
釈然としませんが、今度はIP直指定してみます。
まずはMariaDBコンテナのIPを調べます。
sh-4.2# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 c376bb48006c
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2814f7b46798 php7:user "/sbin/init" 5 days ago Up 3 hours 9000/tcp, 0.0.0.0:8080->80/tcp php_app
c376bb48006c mariadb:user "/sbin/init" 5 days ago Up 3 hours 0.0.0.0:3306->3306/tcp mariadb
MariaDBコンテナのコンテナIDが「c376bb48006c」なので、恐らく「172.10.0.3」というのがこのコンテナのIPでしょう。
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => '172.10.0.3',
'login' => 'root',
'password' => '',
'database' => 'database',
'prefix' => '',
'encoding' => 'utf8',
);
さて。
Database connection "Mysql" is missing, or could not be created.
SQLSTATE[28000] [1045] Access denied for user 'root'@'ic_v3.dockercompose_default' (using password: NO)
ホスト名がおかしいですね…?
試しに先程作ったa5m2ユーザーで試してみます。
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => '172.10.0.3',
'login' => 'a5m2',
'password' => 'a5m2',
'database' => 'database',
'prefix' => '',
'encoding' => 'utf8',
);
CakePHP is able to connect to the database.
無事繋がりはしたのですが、何か釈然としない。。
これも「gateway」ホストからのアクセスと見なされているのでしょうか。。
原因
別コンテナ=別ホストらしいので、DBコンテナのIPを調べて直に指定する。
その際は、ホストPCからのアクセスとなるらしい?ので、ホストからアクセスするのと同等の権限を持ったユーザーを設定する必要がある。
まとめ
とりあえず、外部ホストからアクセス出来てroot同様の権限を持つユーザーをMariaDB上に作らないといけない。
そして、基本そのユーザーを使ってアレコレする。
おまけ
公式のMariaDBコンテナを使わずに、自作したから随所でハマっているような気がしなくもないです。
Ubuntuを避けてきましたが、ここらでUbuntuにも慣れないといけませんね。。
探し方が悪いのか、コンテナ連携や実際のアプリでの運用について説明しているサイトが意外と少なくて、割と手当たり次第やってる感が強いです。
Hyper-V+DockerでのPHP開発環境構築は、まだまだ前途多難なようです。。