環境情報
2019/12/13 時点
- MacOS X 10.15.1(19B88)
- Docker 19.03.5
- nginx 1.17.6
- php-fpm 7.4.0
- MySQL 8.0.18
事前準備
Mac用のdocker-for-mac
をインストールする必要があります。
インストールする際、Docker Hubのアカウントが必要になりますので、事前にDocker Hubへのアカウント登録を済ませておいてください。
$ docker --version
Docker version 19.03.5, build 633a0ea
環境構築
基本的にはdocker-composeを使って環境構築を進めていきます。
nginxの構築
以下のディレクトリ構成を前提に環境構築を進めていきます。
.
├── docker-compose.yml
├── php-docker.md
└── web
├── conf
│ └── default.conf
└── src
└── index.html
default.confファイルの内容
server {
listen 80;
server_name 127.0.0.1;
#ドキュメントルートの設定
root /var/www/;
index index.html index.htm;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
index.htmlファイルの内容
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ようこそDocker</title>
</head>
<body>
<h1>ようこそDocker!</h1>
</body>
</html>
docker-compose.ymlファイルの内容
version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./web/conf/default.conf:/etc/nginx/conf.d/default.conf
- ./web/src:/var/www/
- version
- Docker 19.03.5に対応しているdocker-composeのファイルフォーマットは
3.7
なので、yamlのversionには3
を指定する。 - 対応バージョンの確認はこちらから確認してください。
- Docker 19.03.5に対応しているdocker-composeのファイルフォーマットは
- services -> web は、任意の名前をつけられます。今回はnginxをWebサーバーとして利用する環境構築となり、わかりやすい名称として
web
と定義しています。 - services -> web -> image に設定している
nginx:latest
は、docker hubのnginxでどのバージョンに対応しているかなどが確認できます。- ここではlatestとしていますが、
1.17.6
と指定しても同じ結果になります。(2019/12/13時点では。)
- ここではlatestとしていますが、
- services -> web -> ports の
80:80
は、ホスト(ここではMacPC)で受け付けたポート80
へのリクエストを、Dockerコンテナの80
ポートに転送するという設定です。ポートフォワーディング
- volumes ホスト側で編集したソースやconfなどをDockerコンテナと同期するための設定。
nginxの環境構築が正常に完了しているか動作確認
カレントディレクトリをdocker-compose.yml
のあるディレクトリに移動して、下記コマンドを実行します。
$ docker-compose up -d
Creating network "php-docker_default" with the default driver
Pulling web (nginx:latest)...
latest: Pulling from library/nginx
000eee12ec04: Pull complete
eb22865337de: Pull complete
bee5d581ef8b: Pull complete
Digest: sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
Status: Downloaded newer image for nginx:latest
Creating php-docker_web_1 ... done
nginxのDockerコンテナが正常に動作しているか確認するため以下のURLにアクセスします。
http://127.0.0.1/
「ようこそDocker!」というページ(index.htmlで作ったページ)が表示されればOKです。
いったん起動したnginxのコンテナを停止します。
$ docker-compose stop
Stopping php-docker_web_1 ... done
ここまでで、dockerによるnginx環境の構築がいったん完了です。
php-fpm 7.4の環境構築
以下のディレクトリ構成を前提に環境構築を進めていきます。
.
├── docker-compose.yml
├── php
│ └── src
│ ├── html
│ └── index.php
├── src
│ └── html
└── web
├── conf
│ └── default.conf
└── src
└── index.html
default.confファイルの内容
server {
listen 80;
server_name 127.0.0.1;
#ドキュメントルートの設定
root /var/www/;
index index.php index.html index.htm;
location / {
# 指定された順序でfileやdirの存在を確認し、最初に見つかったものを返却する。
# いずれも無かった場合は、最後に指定されたパスに遷移する。
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# php-fpmのコンテナである「app」のポート9000に対してリクエストのパスを設定
fastcgi_pass app:9000;
# 1台のサーバーでnginx+php-fpmを動作させる場合、Unixソケットの方が高速に動作するため、
# 以下の設定をするが、今回はnginxとphp-fpmを別のコンテナにしているため、ポートでの接続となっている。
# fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
index.phpファイルの内容
<?php
phpinfo();
docker-compose.ymlファイルの内容
version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
depends_on:
- app
volumes:
- ./web/conf/default.conf:/etc/nginx/conf.d/default.conf
#- ./web/src:/var/www/ PHP側でソースを管理するためコメントアウト
app:
image: php:7.4.0-fpm
volumes:
- ./php/src:/var/www/
カレントディレクトリをdocker-compose.yml
のあるディレクトリに移動して、下記コマンドを実行します。
$ docker-compose up -d
にアクセスしてphpinfo()の実行結果が確認できれば完了。
php 7.4.0 って2019年11月28日にビルドされたんですねぇ
MySQL 8.0.18の環境構築
上記までで nginx + php での環境構築が完了しているので、あとはデータベースサーバーであるMySQLを追加していきます。
mysqlフォルダ配下の構成が増えているファイルやフォルダです。
また、PHP7.4のDockerコンテナイメージには、デフォルトでPDO(PHP Data Objects)のMySQLドライバがセットアップされていません。(デフォルトはsqliteのみ)
そのため、phpフォルダ 配下にDockerfileを新規で追加して、phpの環境構築を少し変更する必要があります。
詳細は下記記事でまとめておきました。
docker-compose+MySQL8(8.0.18)+php-fpm(7.4)のPDOでcould not find driverが発生
.
├── docker-compose.yml
├── mysql
│ └── init
│ ├── 10_ddl.sql
│ ├── 20_data_load.sh
│ └── data.csv
├── php
│ ├── Dockerfile
│ └── src
│ └── index.php
└── web
└── conf
└── default.conf
docker-compose.ymlファイルの内容
ここでのポイントは、mysqlのコンテナのvolumes
で指定している2つのマウント指定です。
- 1つはMySQLのデータベースに加えた様々な変更を永続化する(コンテナの起動の度に初期化されないようにする)設定
- もう1つはデータベースを初回だけ初期化するための設定(初回コンテナ起動時に1度だけデータベースを初期化するために実行されるスクリプトを配置するディレクトリをマウントしています。)
また、PHPのコンテナの指定でimage
の指定から、Dockerfileを利用した構築に変更するため、build
の指定を追加しています。
version: '3'
services:
web:
image: nginx:latest
ports:
- "80:80"
depends_on:
- app
volumes:
- ./web/conf/default.conf:/etc/nginx/conf.d/default.conf
app:
#https://hub.docker.com/_/php/
#imageを指定してphpのコンテナを構築するのではなく、Dockerfileを利用した構築方法に変更
#image: php:7.4.0-fpm
build: ./php
volumes:
- ./php/src:/var/www/
mysql:
#https://hub.docker.com/_/mysql
#image: mysql:8.0.18 <-- latestだとこのバージョン(2019/12/13時点)
image: mysql:latest
environment:
#イメージの起動時に作成するデータベースの名前
MYSQL_DATABASE: yudb
#このユーザはMYSQL_DATABASE変数で指定されたデータベースに対してスーパーユーザとしての権限(GRANT ALL)を保持する
MYSQL_USER: mysqluser
#MYSQL_USERのパスワード
MYSQL_PASSWORD: mysqluser00
# MySQLにおけるスーパーユーザであるrootアカウントに設定するためのパスワード
MYSQL_ROOT_PASSWORD: mysqluser000
ports:
- "3306:3306"
volumes:
# /var/lib/mysqlをvolumesで追加する意図として、MySQLのデータベースに加えた変更を永続化するため。
# 例えば、「yudb」という名前でデータベースを作成し、mysqluserを作成し、DDLを流してテーブルを作成し、
# LOAD DATA LOCAL INFILEによってCSVファイルで初期データをロードした場合、/var/lib/mysqlをvolumesに指定しないと、
# MySQLのコンテナを起動するたびに初期化処理が走るようになります。
- ./mysql/var_lib_mysql:/var/lib/mysql
# /docker-entrypoint-initdb.d/配下は、Dockerコンテナが初回起動(初期化)される際に1度だけ実行されるスクリプトなどを配置
# *.sh / *.sql / *.sql.gzの拡張子のファイルはファイル名の昇順に実行される。
- ./mysql/init:/docker-entrypoint-initdb.d
Dockerfileの内容
FROM php:7.4.0-fpm
RUN apt-get update \
&& docker-php-ext-install pdo_mysql
10_ddl.sqlファイルの内容
set global local_infile = 1;
create table if not exists m_sample(
`code` char(3) not null,
`name` varchar(80) not null,
primary key(`code`)
) engine=innodb default charset=utf8;
20_data_load.shファイルの内容
ここでは、shellからMySQLでCSVファイルをテーブルにロードするためのLOAD DATA LOCAL INFILE
を実行する方法を採用しています。
例えば、上記10_ddl.sql
ファイルに以下のような記述を追加することでもCSVファイルをロードできると思いますが、、、
LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/data.csv' INTO TABLE m_sample FIELDS TERMINATED BY ',' ENCLOSED BY '"';
MySQL8のバージョンから、LOAD DATA LOCAL INFILE
を実行すると以下のようなエラーが発生するようになりました。
The used command is not allowed with this MySQL version
原因や対応方法などの詳細な内容は以下の記事でまとめています。
docker-compose+MySQL8(8.0.18)で初期データをCSVロードしようとするとエラー(The used command is not allowed with this MySQL version)に
これらの理由から、shellを利用したCSVファイルのデータロードを選択しています。
mysql -umysqluser -pmysqluser00 yudb --local-infile=1 -e "LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/data.csv' INTO TABLE m_sample FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'"
data.csvファイルの内容
参考までにCSVファイルの内容も載せておきます。
"001","test001"
"002","test002"
"003","test003"
"004","test004"
index.phpの内容
index.phpを変更し、MySQLに登録したデータをvar_dumpで画面に出力するプログラムを作ります。
<?php
$dsn = 'mysql:host=mysql;dbname=yudb';
$user = 'mysqluser';
$password = 'mysqluser00';
try {
$dbh = new PDO($dsn, $user, $password);
$sql = "select * from m_sample";
foreach ($dbh->query($sql, PDO::FETCH_ASSOC) as $row) {
var_dump($row);
}
} catch (PDOException $e) {
var_dump($e);
}
MySQLの環境構築が完了したか確認
$ docker-compose up -d
Creating network "php-docker_default" with the default driver
Creating php-docker_app_1 ... done
Creating php-docker_mysql_1 ... done
Creating php-docker_web_1 ... done
$ docker-compose exec mysql bash
root@83e05bbf0a6a:/# mysql -umysqluser -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> connect yudb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Connection id: 9
Current database: yudb
mysql> show tables;
+----------------+
| Tables_in_yudb |
+----------------+
| m_sample |
+----------------+
1 row in set (0.00 sec)
mysql> select * from m_sample;
+------+---------+
| code | name |
+------+---------+
| 001 | test001 |
| 002 | test002 |
| 003 | test003 |
| 004 | test004 |
+------+---------+
4 rows in set (0.00 sec)
PHPからMySQLのデータが参照できているか確認
以下の取得結果が画面に表示されたことを確認。
array(2) { ["code"]=> string(3) "001" ["name"]=> string(7) "test001" } array(2) { ["code"]=> string(3) "002" ["name"]=> string(7) "test002" } array(2) { ["code"]=> string(3) "003" ["name"]=> string(7) "test003" } array(2) { ["code"]=> string(3) "004" ["name"]=> string(7) "test004" }
これで、一通りの環境構築が完了しました。