Dockerで環境作るの一瞬で便利だよね
下のブログを参考にLAMP環境を作りました。厳密には、Linux使わずDockerだからDAMPだね。
Docker で Apache + PHP + MySQL 環境構築 – WebSpaceBlog
ブログよりも簡略化しています。
Docker-compose.yml
参考ブログと同じにしたので割愛
フォルダ構成
/
├─mysql
│ ├─data
│ │ ├─mysql
│ │ ├─performance_schema
│ │ ├─sys
│ │ └─test
│ └─init
├─php
│ ├─Dockerfile
│ └─php.ini
└─www
└─html
php/Dockerfile
もう最小限です。
FROM php:7.1.5-apache
RUN apt-get update && docker-php-ext-install mysqli pdo_mysql
php/php.ini
module mysqli
だけコメントを解除して入れました
意気揚々とPHPのソース作ってたら詰まった
で、以下のソースを作ったところ、エラーが出ました。
www/html/index.php
<!DOCTYPE html>
<html>
<head><title>テストだ</title>
<?php
$link = mysqli_connect('localhost','root','password','test');
mysqli_set_charset($link,'utf8');
$result = mysqli_query($link, 'SELECT * from link');
$row = mysqli_fetch_assoc($result);
?>
</head>
<body>
※省略
</body>
<html>
エラー
Warning: mysqli_connect(): (HY000/2002): No such file or directory in /var/www/html/index.php on line 5
No such file or directoryとは?
SQLサーバーがうまく指定できていないのかな?というところは行き着いたので、docker-compose.ymlで指定しているMySQLのポートを指定。次のように変えたけれどうまく行かず。
index.php(修正)
mysqli_connect('localhost:3306','root','password','test');
エラー2回目
Cannot assign requested address in /var/www/html/index.php on line 5
Cannot assign requested addressだなんて、もうアドレスとして認識されてないじゃないですか、ヤダー。
結論
どうもMySQLサーバーに対する指定の仕方が間違っているのは間違いない。これは、仕方あるめえと小一時間調べたところ、以下の記事に行き着く。
Dockerで動かしているMySQLに作成したユーザーでPHPから接続できないときの対処方法 – CodeAid(コードエイド)
エラーの発生する原因を結論からいうと、ユーザー作成時に’localhost’を指定しているからです。
Docker以外で構築されたLAMP環境(例えば:VMのLinux、XAMPP、MAMPなど)ではドメインのlocalhostでMySQLと接続できるためエラーは発生しません。
しかしDockerのMySQLは外部アプリなどからlocalhostで接続することができません。
(中略)
MySQLと接続するときに指定するhostはローカル環境だと一般的には「localhost」となります。
ですがDockerの場合はlocalhostでは接続できず、サービス名で接続する必要があります。
この場合、DockerのMySQLは「mysql」というサービス名で動作しているのでこのような記述となります。
サービス名で接続したあとでDockerではローカルアドレスを自動で割り振ります。
それが、エラーメッセージで表示されていた「172.19.0.3」です。
つまりlocalhost(172.0.0.1)では接続できないのです。
なのでデータベースにユーザーを作成するときにホスト名をlocalhostとすると上記エラーが発生してしまいます。
そんなDockerの仕組みわかんねーよー!
勉強不足なだけですねー。ということで、mysqli_connectをmysqlに指定することとして、最終的にphpを以下のように修正しました。
www/html/index.php
<!DOCTYPE html>
<html>
<head><title>テストだ</title>
<?php
$link = mysqli_connect('mysql','root','password','test');
mysqli_set_charset($link,'utf8');
$result = mysqli_query($link, 'SELECT * from link');
$row = mysqli_fetch_assoc($result);
?>
</head>
<body>
※省略
</body>
<html>
結論
Dockerの仕様はなかなか沼がありそうですねえ…。ちゃんと勉強すればすぐに分かるのかもしれませんが、インターネットで調べながらの付け焼き刃ではいけませんねえ。
日々勉強いたしましょう。