参考:https://qiita.com/fujitak/items/b56122e2ecd94022a7b6
(参考にさせていただきました!ありがとうございました!)
##カスタムネットワークの作成
$ docker network create phm
「phm」は任意の名前
###確認
$ docker network ls
##ディレクトリ構成を決める
├── docker-compose.yml
├── index.php
├── mysql
│ ├── Dockerfile
│ ├── mysql_conf
│ └── custom.cnf
├── php
└── Dockerfile
以下の記事では作業ディレクトリは
/var/www/docker/php-mysql
の前提で記述する。
##Dockerfileの作成
###php/Dockerfile
FROM php:7.2-apache
RUN apt-get update && \
docker-php-ext-install pdo_mysql mysqli #(*1)
WORKDIR /var/www/docker/php-mysql
EXPOSE 80
(*1)元記事ではmbstringもインストールするように設定されていたが、すでに入っているということでエラーになる。
###mysql/Dockerfile
FROM mysql:8.0
###docker-compose.yml
version: "3"
services:
app:
container_name: php
build:
context: ./php
dockerfile: Dockerfile
tty: true
volumes:
- .:/var/www/html #(※2)
ports:
- "8000:80" #(※3)
network_mode: "phm"
db1:
container_name: mysql
build:
context: ./mysql
dockerfile: Dockerfile
environment:
- MYSQL_ROOT_PASSWORD=pass
volumes:
- ./mysql/mysql_conf:/etc/mysql/conf.d #(※4)
network_mode: "phm"
networks:
phm:
(※2) docker-compose.ymlのあるディレクトリが、コンテナ側の/var/www/htmlにマウントされる。
(※3) 元記事では「80:80」となっていたが、ホスト側にapacheなどが入っていて80番ポートを使っているとエラーになるので変更する。
(※4) mysqlの設定ファイルを置くディレクトリに注意。
##MySQLの設定ファイルを書く
MySQL8ではデフォルトの認証方式が「caching_sha2_password」であり
The server requested authentication method unknown to the client
というエラーが発生するので、認証方式を「mysql_native_password」に変更しておく。
###mysql/mysql_conf/custom.cnf
[mysqld]
default_authentication_plugin=mysql_native_password
##docker-composeを実行
/var/www/docker/php-mysql
に戻ってから、(戻らなくても大丈夫だが、どこのymlが実行されるのか未調査)
$ docker-compose up -d
を実行
##imageの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
php-mysql_app latest e46f7f57f545 About a minute ago 428MB
php 7.2-apache fc63b5c72cff 4 days ago 410MB
mysql 8.0 9228ee8bac7a 4 days ago 547MB
php-mysql_db1 latest 9228ee8bac7a 4 days ago 547MB
##containerの確認
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4aa3317e2d9e php-mysql_app "docker-php-entrypoi…" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp php
8712548172e8 php-mysql_db1 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp mysql
##確認用スクリプト
###index.php
<meta charset="UTF-8">
<title>テスト</title>
<?php
try {
# hostには「docker-compose.yml」で指定したコンテナ名を記載
$dsn = "mysql:host=mysql;dbname=sample;";
$db = new PDO($dsn, 'root', 'pass');
$sql = "SELECT * FROM test";
$stmt = $db->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
} catch (PDOException $e) {
echo $e->getMessage();
exit;
}
##DBエラーを承知でアクセスしてみる
$ curl http://localhost:8000/
<meta charset="UTF-8">
<title>テスト</title>
SQLSTATE[HY000] [1049] Unknown database 'sample'[someone@hoge php-mysql]$
DBの問い合わせまでうまく行っている
##MySQL側の設定
コンテナに入る
$ docker exec -it mysql bash
###MySQLへ接続
# mysql -u root -p
Enter password:
で「pass」と入力。(docker-compose.ymlの「db1」の「environment」で設定)
ユーザーの確認
select user,host from mysql.user;
root@localhost
が存在していたら削除(しないと、そっちが優先されて接続できない)
drop user root@localhost;
適当なデータベースとテーブルを作成
mysql> CREATE DATABASE sample;
mysql> USE sample;
mysql> CREATE TABLE test(id int AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));
mysql> INSERT INTO test (name) VALUES ('John');
##再びアクセスしてみる
$ curl http://localhost:8000/
<meta charset="UTF-8">
<title>テスト</title>
array(1) {
[0]=>
array(2) {
["id"]=>
string(1) "1"
["name"]=>
string(4) "John"
}
}
成功。
##(余談)ちなみに、phpコンテナに入ってみる
$ docker exec -it php bash
# cd /var/www/html
# ls
docker-compose.yml index.php mysql php php-mysql
と出て、docker-compose.yml で設定したvolumesの通りマウントされていることがわかる
volumes:
- .:/var/www/html
↑ この部分。