4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DockerのLAMP環境でPHPからMySQL接続に詰まった話

Last updated at Posted at 2020-08-12

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の仕様はなかなか沼がありそうですねえ…。ちゃんと勉強すればすぐに分かるのかもしれませんが、インターネットで調べながらの付け焼き刃ではいけませんねえ。

日々勉強いたしましょう。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?