PHP
MySQL
docker

Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)構築

More than 1 year has passed since last update.

やること

  • Docker Hubのオフィシャルイメージを一行で立ち上げる
  • データの置き場所を考える
  • Dockerfileによるイメージのカスタマイズ
  • Dockerfileを使わないカスタマイズ
  • イメージの連携

ホスト側の環境

今回はUbuntu 16.04の64it版ISOをインストールしました。Dockerは32bitのOSでは動かないのでご注意。

仮想環境で使う場合は、

vagrant init ubuntu/xenial64
vagrant up

こんな感じで。

Dockerのインストール

http://docs.docker.com/linux/step_one/
こちらを参考に。

wget -qO- https://get.docker.com/ | sh

これで最新のDockerパッケージを導入できます。

PHP+Apacheのイメージを使ってみる

Docker Hub のオフィシャルリポジトリを使います。

とりあえず起動してみる

docker run -d php:5.6-apache

PHP+ApacheのイメージをDocker Hubから取得し、コンテナを起動します。

docker images

取得したイメージ一覧を表示します。

docker ps

起動しているコンテナ一覧を表示します。STATUSの欄がUpになっていれば起動しています。

ブラウザで確認してみる

上の方法では、起動しているコンテナのポートが内部で閉じているのでブラウザで確認することはできません。そこでコンテナのポートを公開してみます。

docker run -p 80:80 -d php:5.6-apache

-pオプションでホストのポートとコンテナのポートを結びつけます。コロンの左側がホスト側、右側がコンテナ側のポート番号です。

ブラウザでサーバーのURLを開き「Forbidden」のメッセージが出れば成功です。

コンテナを消す

次に進む前に、使ったコンテナを消しておきます。

docker rm -f コンテナID

これで削除できます。コンテナIDは

docker ps -a

で調べることができます。

面倒なら、

docker rm -f $(docker ps -a -q)

これでコンテナを一括ですべて削除することもできます。

コンテンツを作成する

お次はHTMLなどのウェブコンテンツを入れてみます。コンテナ内にファイルを導入する方法はいくつかありますが、今回は2つの方法を試してみます。

1. コンテナに入ってファイルを作成する

docker run -p 80:80 --name php -d php:5.6-apache

先ほどと同じ起動方法ですが、分かりやすいように--nameオプションでコンテナにphpという名前を付けています。

docker exec -ti php bash

これでphpコンテナ内に入ることができます。-tiを付けないとターミナルを開くことができません。
コンテナ内にいるときはプロンプトにコンテナIDが付きます。

ドキュメントルートの/var/www/htmlにいるはずなので、この場でHTMLファイルを作成すれば良いのですが、テキストエディタがインストールされていません。インストールしても構いませんが、とりあえずechoで書きます。

echo '<?php phpinfo();' > index.php

ブラウザでサーバーのURLを開きphpinfoの画面が出てくれば成功です。

2. コンテナのディレクトリとホストのディレクトリを結びつける

コンテナは永続化されないので、コンテナを削除するとコンテナ内で作成したファイルも消えてしまいます。そこでホスト側にファイルを置き、そのディレクトリをコンテナ側から参照する手法を取ってみます。

ホスト側のファイルを置くディレクトリは今回/docker/wwwにしました。が、別にどこでも構いません。
まず /docker/www/index.php を作成します。

index.php
<?php phpinfo();

以前のコンテナを削除してから以下を実行します。

docker run -p 80:80 -v /docker/www:/var/www/html --name php -d php:5.6-apache

-vオプションでホストのディレクトリとコンテナのディレクトリを結びつけます。コロンの左側がホスト側、右側がコンテナ側のディレクトリです。

ブラウザでサーバーのURLを開きphpinfoの画面が出てくれば成功です。

MySQLのイメージを使ってみる

こちらもDocker Hub のオフィシャルリポジトリを使います。

起動してコマンドラインから操作してみる

docker run --name mysql -e MYSQL_ROOT_PASSWORD=pass -d mysql:5.7

MySQL 5.7のイメージをDocker Hubから取得し、起動します。
-eオプションは環境変数を設定するもので、rootのパスワードをpassに設定しています。

docker exec -ti mysql bash

これでコンテナ内に入り、

mysql -ppass

MySQLの操作ができます。

PHPとMySQLの連携

次にPHPとMySQLの2つのコンテナを連携してみます。
先に今まで作成したコンテナを削除しておいてください。

DockerfileによるPHPイメージのカスタマイズ

オフィシャルのPHPコンテナは最小限のオプションでコンパイルされているので、そのままではMySQLと連動するのが難しいです。そこでDockerfileを使うと、既にあるイメージをカスタマイズして新しいイメージを作ることができます。

Dockerfileの場所はどこでもよいのですが、今回は /docker/php/ に作成します。
ホスト側で /docker/php/Dockerfile を以下の内容で作成します。

FROM php:5.6-apache
RUN apt-get update && \
  docker-php-ext-install pdo_mysql mysqli mbstring

FROMは元となるイメージを指定します。
RUNでコマンドを指定します。docker-php-ext-installはphp:5.6-apacheイメージに含まれるユーティリティで、オプションを追加してPHPをリコンパイルするものらしいです。

Dockerfileが用意できたら、新しいイメージをビルドします。

docker build -t php:custom /docker/php

これで /docker/php にあるDockerfileを元にphp:customというイメージを作成します。docker imagesで確認してみてください。

MySQLイメージの設定を変更する

先に今まで作成したコンテナを削除しておいてください。

Docker HubのMySQLイメージはcharacter setがlatin1になっている部分がありますので、設定ファイルを追加してみます。
/docker/mysql/custom.cnf (場所とファイル名は任意です)を以下の内容で作成します。

[mysqld]
character-set-server=utf8

この設定ファイルを読み込んでMySQLコンテナを起動します。

docker run --name mysql -v /docker/mysql:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=pass -d mysql:5.7

-vオプションでホスト側の /docker/mysql ディレクトリとコンテナ側の /etc/mysql/conf.d ディレクトリを結びつけています。
MySQLコンテナの設定ファイルは /etc/mysql/my.cnf ですが、その中で /etc/mysql/conf.d にある設定ファイルをすべて読み込むようになっているので、作成した custom.cnf が読み込まれる仕組みです。

PHPコンテナをMySQLコンテナとリンクして起動する

いよいよPHPコンテナとMySQLコンテナを連携します。

docker run -p 80:80 -v /docker/www:/var/www/html --link mysql:mysql --name php -d php:custom

--linkオプションでコンテナmysqlを連携します。コロンの右側で連携する名前を指定します。

連携が取れているか確認してみましょう。

docker exec -ti php bash

でPHPコンテナに入り、envコマンドや /etc/hosts を開きMySQLコンテナの情報が入っているか確認します。

/etc/hosts
172.17.0.36     mysql

このように先ほど--linkで指定した名前でホスト名にアクセスできます。

phpMyAdminを導入して確認する

連携の確認用にphpMyAdminをホスト側に導入します。

cd /docker/www
wget https://files.phpmyadmin.net/phpMyAdmin/4.4.13.1/phpMyAdmin-4.4.13.1-all-languages.tar.gz
tar zxf phpMyAdmin-4.4.13.1-all-languages.tar.gz
rm phpMyAdmin-4.4.13.1-all-languages.tar.gz
mv phpMyAdmin-4.4.13.1-all-languages myadmin
cd myadmin/
cp config.sample.inc.php config.inc.php
config.inc.php
$cfg['Servers'][$i]['host'] = 'mysql';

hostをlocalhostから--linkオプションにより設定されたホスト名mysqlに変更します。

ブラウザで開いてみて、ID:root、PW:passでログインできれば成功です。

PDOのサンプル

最後にひとつPDOのサンプルを作成します。

まずphpMyAdminでデータベースとテーブルを適当にひとつ作成します。

CREATE DATABASE test;
USE test;
CREATE TABLE test(name VARCHAR(100));

次に /docker/www/test.php を以下の内容で作成します。

test.php
<meta charset="UTF-8">
<title>テスト</title>
<?php
$db = new PDO('mysql:host=mysql;dbname=test', 'root', 'pass');
$db->query("INSERT INTO test VALUES('テスト太郎')");
$st = $db->query("SELECT * FROM test");
var_dump($st->fetchAll());

ブラウザでtest.phpを開いてみて、データの挿入と表示が出来ていることを確認します。

感想

イメージやコンテナの作成と破棄がすごくお手軽なので、今までのやり直しが効かないサーバー管理から解放される感がありました。