Chapter 05

Docker Compose を使う

ほげさん
ほげさん
2021.08.14に更新

この章で理解できること

前の章で作った 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:centos7command: 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します。
-ddocker 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 ]

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