Dockerを使ってPHP7+Apache+MySQLの開発環境を作る
今回は前回に引き続き実技試験の予習として開発環境を作っていく
前回はPHP7+Apacheまで作ったのでMySQLを含めた環境を作っていく
carametal.hatenablog.com
こちらの記事を参考にさせていただきました。
こちらの記事ではMySQLクライアントにphpMyAdminを使っていますが
ひとまず環境構築のみの目的なのでphpMyAdminは扱いません。
前回の記事ではDockerfileを用いていましたが今回はdocker-composeで環境を作っていきます。
手始めにdocker-compose.ymlを作成
version: '3' services: php: image: php:7.2-apache volumes: - ./html:/var/www/html ports: - 8000:80 container_name: php7.2-trial2 mysql: image: mysql:5.7 volumes: - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=test - MYSQL_USER=test - MYSQL_PASSWORD=test container_name: mysql5.7-trial2
ほとんど参考にさせていただいた記事からの流用ですが
phpのimageは前回記事同様にphp:7.2-apacheを使用
volumes項目でカレントディレクトリにあるhtmlディレクトリを
コンテナ内の/var/www/htmlにマウント
公開ポートは8000番、ポートフォワーディング先は80番に指定
ビルド後のコンテナ名にphp7.2-trial2を指定
mysqlのimageにはmysql5.7を使用
volumes項目で./mysqlを/var/lib/mysqlにマウント(ここはよくわかっていないけどディレクトリがなくてもdocker-compose up したときに自動的に作られるみたい※要調査)
environment項目では環境変数を設定し
コンテナ名にmysql5.7-trial2を指定
docker-compose.ymlはこれで完了
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>php7.2-apache</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <?php echo 'Hello world.'; ?> </body> </html>mysql5.7-trial2
index.phpは一旦echoでHello world.するようにする(あとでDBのデータを取得するように変更します)
最後にphp.ini
phpの設定ファイルなわけですが今回はお試し環境構築なのでこちらから拝借させていただきました
qiita.com
以上で必要なファイルはそろいました
docker-compose up -d
でコンテナの作成&実行する
docker container ps
を実行してphp7.2-trial2とmysql5.7-trial2の2つのコンテナが起動していれば成功
http://localhost:8000/にアクセスしてHello worldと表示されるはず
次はMySQLにアクセスしてDBから取得したtextを表示してみる
まずはmysql5.7-trial2コンテナに入って
docker exec -it mysql5.7-trial2 bash
MySQLにログイン
mysql -uroot -proot
- uはログインユーザの指定
- pはパスワードの指定
この2つはdocker-composeで指定したものを使用する
mysqlにログインできたら
show databases;
とするとMYSQL_DATABASEにtestと設定しているので一覧にtestというDBがあるはず
use test; show tables;
当然まだtableはまだないはずなのでEmpty set (~~~ sec)と表示されるはず
tableを作ってテストデータを作る
create table test (id int not null auto_increment, text char(30), primary key (id)); insert into test (text) values ('first test.'); insert into test (text) values ('second test.'); insert into test (text) values ('second test.');
select * from test;
で
+----+--------------+ | id | text | +----+--------------+ | 1 | first test. | | 2 | second test. | | 3 | third test. | +----+--------------+
これが出たら準備は完了
index.phpを修正する
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>php7.2-apache</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <?php try { $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); foreach($dbh->query('select * from test') as $row) { echo $row['text'] . '<br>'; } $dbh = null; } catch (PDOException $e) { echo $e; die(); } $dbh = null; ?> </body> </html>
これでtestデータベースのtestテーブルのデータが表示される
と思ったが
Fatal error: Uncaught PDOException: could not find driver in /var/www/html/index.php:11
というエラーが
どうやらPDO(PHP Data Object)にMySQL用のドライバーがないというエラーの模様
今回の対応として公式のphp:7.2-apacheではなくドライバー入りのimageを作って
そっちを使うようにする
まず、以下のようなDockerfileを作る
FROM php:7.2-apache RUN docker-php-ext-install pdo_mysql
そしてこれをbuildする
docker image build -t php7.2-apache-trial2 . ||> このとき、php.iniやhtmlディレクトリのあるディレクトリでビルドすると下記のようなエラーが出ることがあるので注意 >|| error checking context: 'no permission to read from '/home/carametal/dev/docker/soltwarks/trial2/mysql/ca-key.pem''.
これはカレントディレクトリ配下をDockerfile内の命令からアクセス可能な範囲として指定されるため発生するらしい(以下の記事参照)
developer-collaboration.com
imageのビルドができたらdocker-compose.ymlを修正
version: '3' services: php: image: php7.2-apache-trial2 volumes: - ./html:/var/www/html ports: - 8000:80 container_name: php7.2-trial2 mysql: image: mysql:5.7 volumes: - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=test - MYSQL_USER=test - MYSQL_PASSWORD=test container_name: mysql5.7-trial2
phpの指定imageをphp:7.2-apacheから今回新しくbuildしたphp7.2-apache-trial2に変更するだけ
さぁこれでDBから取得したデータが表示されるはず
PDOException: could not find driver in /var/www/html/index.php:12 Stack trace: #0 /var/www/html/index.php(12): PDO->__construct('mysql:host=mysq...', 'root', 'root') #1 {main}
と思いきやこのようなエラーメッセージが出てきてしまった
これは正直めちゃくちゃハマったんだけどこちらの記事のおかげで助かりました
qiita.com
内部的にどんな処理になってるのかわからないんだけど
PDOのコンストラクタに渡すhostはlocalhostではだめで
<?php // NG $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); //OK $dbh = new PDO('mysql:host=mysql5.7-trial2;dbname=test', 'root', 'root');
docker-compose.ymlのcontainer_nameで指定しているコンテナ名にしなければならないらしい
ローカルにそのままMySQLサーバーを立てるんだったらlocalhostでいいんだろうけど
Dockerを使っている場合はコンテナ名を指定しなきゃいけない
ということでhttp://localhost:8000/にアクセスしたら
first test. second test. third test.
と表示されます
なんとかphp7+Apache+MySQL開発環境をDockerで作る目標を達成しました。
Dockerもいいけど明日からは実技試験に向けてPHPのコードを書いていきたい
面接とSPI試験の対策もしておかなきゃなぁ