やること
- 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 を作成します。
<?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コンテナの情報が入っているか確認します。
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
$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 を以下の内容で作成します。
<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を開いてみて、データの挿入と表示が出来ていることを確認します。
感想
イメージやコンテナの作成と破棄がすごくお手軽なので、今までのやり直しが効かないサーバー管理から解放される感がありました。