DockerでMySQL、PHP、Apacheを連携させる
きっかけ
MySQLサーバのTimeZoneがUTCで、アプリケーションのTimeZoneがAsia/Tokyoの場合に、実際のところどうなるか確認したかった。
ということでDockerの勉強も兼ねてMySQLとPHP/Apacheの2種類のイメージを連携させる方法を調べたのでメモります。
いつものように先人の知恵はこちら
今回使ったイメージは公式のイメージを利用しています。
- mysql:5.7
- php:5.6-apache
- 今回はこれをベースにPDO MySQLを追加した
MySQLサーバ起動
上記の公式イメージを取得し、ローカルでコンテナ起動
$ docker pull mysql:5.7 $ docker run --name mysqld -e MYSQL_ROOT_PASSWORD=pass -d mysql:5.7
ここでは、ROOTのパスワードを指定しています。 パスワード以外にもいろいろと指定できますので、本格的なWebアプリケーション用に構築するならばDocker Hubや参考サイトを確認してください。
MySQLクライアントの起動
同じイメージにはMySQLのクライアントも入っているので、別のコンテナとして起動します。 --linkオプションを付けることで、先ほど起動したmysqldと連携させることが出来ます。
$ docker run --link mysqld:mysql -it --rm mysql /bin/bash
MySQLクライアントからMySQLサーバに接続
Dockerのコンテナに入れたら以下のコマンドでMySQLサーバに接続できます。
# mysql -u root -ppass -h $MYSQL_PORT_3306_TCP_ADDR
$MYSQL_で始まる環境変数は他にも定義されいますので、env
コマンドなどで確認してください。
接続できたら、てけとうなDBとテーブルを作ります。
CREATE DATABASE mydb; USE mydb; CREATE TABLE users( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(32), created TIMESTAMP ); INSERT INTO users(name, created) VALUES('山田', NOW());
PHPのイメージ準備
公式のphp:5.6-apacheをベースにして、PDO MySQLを追加インストールしたイメージを作成します。
FROM php:5.6-apache RUN apt-get update && \ docker-php-ext-install pdo_mysql
これをベースにイメージをビルドします
$ docker build -t php:5.6-apache-pdo-mysql .
PHPコンテナ起動
PHPのイメージがビルドできたら、適当なディレクトリをマウントして起動します。 今回はApacheが同梱されたイメージですが、PHPのCLIを使って確認します。
$ docker run --link mysqld:mysql -it --rm -v `pwd`:/var/www/html php:5.6-apache-pdo-mysql /bin/bash
UTCのMySQLとAsia/TokyoのPHPプログラムの変換
次のようなプログラムで確認してみました。
実行すると1レコードINSERTします。created
にはNOW()
で値を入れているためUTCでの時刻として表示されます。
なので、$row['created']
は、UTCでの日時表記となっています。
このサンプルではDateTime
クラスを使ってUTCからAsia/Tokyoへの変換を行っています。
<?php // default timezone=Asia/Tokyo date_default_timezone_set('Asia/Tokyo'); // connect DB $db = new PDO('mysql:host=mysql;dbname=mydb', 'root', 'pass'); // sample record $db->query("INSERT INTO users(name,created) VALUES('ほげほげ', NOW())"); $st = $db->query("SELECT * FROM users"); $rows = $st->fetchAll(); foreach ($rows as $row) { $user = []; $user['name'] = $row['name']; // retrieve as UTC $dt = new DateTime($rows['created'], new DateTimeZone('UTC')); // set default timezone $dt->setTimeZone(new DateTimeZone(date_default_timezone_get())); $user['created'] = $dt->format('Y-m-d H:i:s'); var_dump($user); }
PHPから値を入れる際には、一工夫必要になる気がしますが、それは今後のお話で。