Docker Compose入門(2)

DOCKER超入門(2)WEBアプリで作った Apache + MySQL の構成を、Docker Compose で構築します。
前記事で理解したことは、以下の通りです。

この章では、それぞれをこう置き換えます。
Docker の場合 | Docker Compose の場合 |
---|---|
docker build の -f docker/apache/Dockerfile . | build: docker/apache |
docker build の -f docker/mysql/Dockerfile . | build: docker/mysql |
docker network create php-sandbox-app | |
docker run の--network-alias app | app: |
docker run の-v $(pwd)/src:/var/www/html | volumes: [ ./src:/var/www/html ] |
docker run の-p 8080:80 | ports: [ 8080:80 ] |
docker volume create php-sandbox-db | volumes: php-sandbox-db: |
docker run の-v php-sandbox-db:/var/lib/mysql | volumes: [ php-sandbox-db:/var/lib/mysql ] |
上記の結果を整理した絵はこの通りです。

Docker で Apache + MySQL を構成するときの問題
前記事を整理した図を見てわかる通り、今の構成を Docker コマンドで用意するには手順とオプションを正しく再現する必要があります。
前記事の構成
docker build
docker build
docker network create
docker volume create
docker run
--network
--network-alias
-v
-p
docker run
--network
--network-alias
-v
これに対して、Docker Compose はdocker-compose.yml
に従って Docker イメージのビルドや起動・停止を一元管理してくれるツールです。
コマンドを決められた順番かつきっちりオプションまで記したマニュアルを作るくらいなら、それらをdocker-compose.yml
で共有しましょう。
Docker Compose の設定をする
docker-compose.yml を用意
docker-compose.yml
を用意して、今まで手作業で構築していたことを書き写していきます。
Apache と MySQL のコンテナを 2 つ用意するので、services:
にweb:
とdb:
を定義します。[1]
docker-compose.yml
version: '3.7'
services:
web:
db:
Apache コンテナと MySQL コンテナの Dockerfile の指定
イメージの作り方を指定します。
Docker の場合 | Docker Compose の場合 |
---|---|
docker build の -f docker/apache/Dockerfile . | build: docker/apache |
docker build の -f docker/mysql/Dockerfile . | build: docker/mysql |
docker-compose.yml
version: '3.7'
services:
+ web:
+ build: docker/apache
+ db:
+ build: docker/mysql
!
build:
はDockerfile
のあるディレクトリを指定します。
また、build:
ではなくimage: centos:centos7
とcommand: yum install ...
でDockerfile
を使わずにイメージを作ることもできます。
Apache コンテナと MySQL コンテナの Network の指定
コンテナで共有するネットワークですが、services:
の下に書いたweb:
とdb:
がそのままエイリアスとして使えます。
Docker の場合 | Docker Compose の場合 |
---|---|
docker network create php-sandbox-app | |
docker run の--network-alias app | app: |
なのでdocker-compose.yml
の修正はありません。
docker-compose.yml
version: '3.7'
services:
web:
build: docker/apache
db:
build: docker/mysql
ただエイリアスがapp
からdb
になってしまったので、index.php
の$hostname
を修正します。
index.php
- $mysqli = new mysqli('app', 'root', 'secret', 'sandbox');
+ $mysqli = new mysqli('db', 'root', 'secret', 'sandbox');
Apache コンテナの Bind Mount の指定
Bind Mount の設定をweb:
のvolumes:
で指定します。
Docker の場合 | Docker Compose の場合 |
---|---|
docker run の-v $(pwd)/src:/var/www/html | volumes: [ ./src:/var/www/html ] |
docker-compose.yml
version: '3.7'
services:
web:
build: docker/apache
+ volumes: [ ./src:/var/www/html ]
db:
build: docker/mysql
Apache コンテナの Port Mapping の指定
Port Mapping の設定をweb:
のports:
で指定します。
Docker の場合 | Docker Compose の場合 |
---|---|
docker run の-p 8080:80 | ports: [ 8080:80 ] |
docker-compose.yml
version: '3.7'
services:
web:
build: docker/apache
volumes: [ ./src:/var/www/html ]
+ ports: [ 8080:80 ]
db:
build: docker/mysql
MySQL コンテナの Named Mount の指定
Named Mount は、Volume の作成と利用の指定で行います。
Docker の場合 | Docker Compose の場合 |
---|---|
docker volume create php-sandbox-db | volumes: php-sandbox-db: |
docker run の-v php-sandbox-db:/var/lib/mysql | volumes: [ php-sandbox-db:/var/lib/mysql ] |
docker-compose.yml
version: '3.7'
services:
web:
build: docker/apache
volumes: [ ./src:/var/www/html ]
ports: [ 8080:80 ]
db:
build: docker/mysql
+ volumes: [ php-sandbox-db:/var/lib/mysql ]
+
+ volumes:
+ php-sandbox-db:
Docker Compose の実行
docker-compose.yml
が完成しました。
docker-compose.yml
version: '3.7'
services:
web:
build: docker/apache
volumes: [ ./src:/var/www/html ]
ports: [ 8080:80 ]
db:
build: docker/mysql
volumes: [ php-sandbox-db:/var/lib/mysql ]
volumes:
php-sandbox-db:
可能な限りいろいろ削除して、一覧を確認しておきます。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker volume ls
DRIVER VOLUME NAME
$ docker network ls | grep -ve 061 -ve 2ab -ve 0b5 # 消せないのを除外
NETWORK ID NAME DRIVER SCOPE
イメージがないので--build
を付けてup
します。-d
はdocker run
と同じくバックグラウンド実行フラグです。
$ docker-compose up -d --build
Creating network "php-sandbox_default" with the default driver
Creating volume "php-sandbox_php-sandbox-db" with default driver
Building web
:
:
Successfully built 39c895176f8ce8310a831f91b4b6a3f598b12966b183a5f3cdf436ef2890cc79
Building db
:
:
Successfully built e4401f0f0d624d588b0e488bd3605fd3e9f8f42d00aef4ccc8b002ae2115c30d
Creating php-sandbox_db_1 ... done
Creating php-sandbox_web_1 ... done
いろいろ確認します。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
php-sandbox_db latest e4401f0f0d62 1 minutes ago 449MB
php-sandbox_web latest 39c895176f8c 1 minutes ago 368MB
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bce7efcdb4fc php-sandbox_web "docker-php-entrypoi…" 2 minutes ago Up About a minute 0.0.0.0:8080->80/tcp php-sandbox_web_1
1224bcaffb8a php-sandbox_db "docker-entrypoint.s…" 2 minutes ago Up About a minute 3306/tcp, 33060/tcp php-sandbox_db_1
$ docker volume ls
DRIVER VOLUME NAME
local php-sandbox_php-sandbox-db
$ docker network ls | grep -ve 061 -ve 2ab -ve 0b5
NETWORK ID NAME DRIVER SCOPE
5408de510b40 php-sandbox_default bridge local
docker-compose.yml
に書いた通りの結果になっています。
Volume が変わったのでまたテストデータを入れて、ブラウザで確認しましょう。テストデータ準備
$ docker exec -it 1224bcaffb8a mysql -p
Enter password: # secret
use sandbox;
create table items (id int, name varchar(10));
insert into items values (1, 'John');
insert into items values (2, 'Jane');

前の章と同じく、WEB サーバでindex.php
を動かして DB に MySQL を使えていることが、ホストマシンのブラウザから確認できました。
複数のコマンドとオプションをdocker-compose.yml
で全て指定することができたので、プロジェクトでの共有が格段にしやすくなりました。
やることはこれだけです。
$ git clone ...
$ cd ...
$ docker-compose up -d --build
整理: この章のまとめ
冒頭のまとめを再掲します。

Docker の場合 | Docker Compose の場合 |
---|---|
docker build の -f docker/apache/Dockerfile . | build: docker/apache |
docker build の -f docker/mysql/Dockerfile . | build: docker/mysql |
docker network create php-sandbox-app | |
docker run の--network-alias app | app: |
docker run の-v $(pwd)/src:/var/www/html | volumes: [ ./src:/var/www/html ] |
docker run の-p 8080:80 | ports: [ 8080:80 ] |
docker volume create php-sandbox-db | volumes: php-sandbox-db: |
docker run の-v php-sandbox-db:/var/lib/mysql | volumes: [ php-sandbox-db:/var/lib/mysql ] |

脚注
web:
とdb:
の部分は任意名です ↩︎