【ペチオブ】仮想環境ハンズオン 第5回 Docker Compose編

# Docker Composeハンズオン

## ハンズオン資料

1. [Linux基礎編](https://qiita.com/ucan-lab/items/683658dbeb6f81c4c73f)
2. [VirtualBoxハンズオン](https://qiita.com/ucan-lab/items/d06f9ab9946598b53421)
3. [Vagrantハンズオン](https://qiita.com/ucan-lab/items/e14a26081229c8bef98a)
4. [Dockerハンズオン](https://qiita.com/ucan-lab/items/6e6a7d7d40c7287b6af9)
5. **Docker Composeハンズオン**

## 今回の目的

今回の目的は、VirtualBox上にVagrantを使ってUbuntu OSのインストール、PHPの実行環境の構築を行います。

## YouTube版 【ペチオブ】仮想環境ハンズオン 第5回 Docker Compose編

[![【ペチオブ】仮想環境ハンズオン 第5回 Docker Compose編](http://img.youtube.com/vi/eEQabinccSM/0.jpg)](https://youtu.be/eEQabinccSM)

動画を高評価、チャンネル登録いただけるとより多くの方へオススメ表示されるので良いと思った方はご協力いただけるとありがたいです🙏

## 完成版

https://github.com/ucan-lab/infra-handson-docker-compose

完成版はGitHubにプッシュしてます。

## 概要

Composeは、複数コンテナのDockerアプリケーションを定義して実行するためのツールです。

Docker単体だとコンテナ毎にコマンドやオプションをたくさん指定する必要がありましたが、複数のコンテナに対して実行できます。

## ハンズオン

```
$ mkdir docker-compose-handson
$ cd docker-compose-handson
```

## サンプルソースをgit cloneしておく

```
$ git clone https://github.com/ucan-lab/infra-handson-shop shop
```

## php/Dockerfile

```
$ mkdir php
$ vim php/Dockerfile
```

```
FROM php:7.4-apache-buster

ENV DB_HOST=db
ENV DB_NAME=shop
ENV DB_USER=phper
ENV DB_PASS=secret

RUN apt-get update
RUN docker-php-ext-install pdo_mysql
```

- `DB_HOST=db` ここだけDockerハンズオンと異なります。
  - コンテナ名ではなく、サービス名で接続できます。

## mysql/Dockerfile

Dockerハンズオンと同じDockerfileを作ります。コピペしてきてもokです。

```
$ mkdir mysql
$ vim mysql/Dockerfile
```

```
FROM mysql:8.0

ENV MYSQL_DATABASE=shop
ENV MYSQL_USER=phper
ENV MYSQL_PASSWORD=secret
ENV MYSQL_ROOT_PASSWORD=secret

COPY ./my.cnf /etc/my.cnf
```

## mysql/my.cnf

Dockerハンズオンと同じmy.cnfを作ります。コピペしてきてもokです。

```
$ vim mysql/my.cnf
```

```
[mysqld]
character_set_server = utf8mb4 # 文字コード
collation_server = utf8mb4_ja_0900_as_cs # 照合順序
```

## docker-compose.yml

```
$ vim docker-compose.yml
```

```
version: "3.8"
services:
  web:
    build: ./php
    ports:
      - 8200:80
    volumes:
      - ./shop:/var/www/html

  db:
    build: ./mysql
    volumes:
      - db-storage:/var/lib/mysql

volumes:
  db-storage:
```

### YAML (ヤムル)

- [YAML 公式](https://yaml.org)
- [YAML wiki](https://ja.wikipedia.org/wiki/YAML)
- [yamlの書き方](https://qiita.com/fkana/items/21f7cc3b327445483d5c)

YAML Ain't a Markup Language

インデント(字下げ)を使って、データの階層構造を表現する。
そのため、インデントが崩れると実行できなくなるので注意する。

### docker-compose.yml オプション説明

- `version`
  - https://docs.docker.com/compose/compose-file
  - 現時点の最新バージョンは3.8
  - バージョン2系の記述は古いので注意
- `services`
  - コンテナを定義します。
  - `web`, `db` サービスを定義(サービス≒コンテナ)
- `build`
  - Dockerfile が存在するディレクトリを指定する
  - https://docs.docker.com/compose/compose-file/#build
- `ports`
  - ポートを公開します。(ポート転送)
  - ホストのポート:コンテナのポート
- `volumes`
  - ホストパスまたは名前付きボリュームをマウントします。
- `environment`
  - コンテナ内で使用できる環境変数を追加します。

## サービスのコンテナをビルド

```
$ docker-compose build

Building web

...

Successfully built b85983a00e56
Successfully tagged docker-compose-handson_web:latest

Building db

...

Successfully built 4077115f617f
Successfully tagged docker-compose-handson_db:latest
```

## サービスのコンテナを作成、開始

```
$ docker-compose up -d
Starting docker-compose-handson_web_1 ... done
Starting docker-compose-handson_db_1  ... done
```

- `-d`, `--detach` Detached mode: Run containers in the background, print new container names.
  - バックグラウンドでコンテナが起動します。

## コンテナの一覧

```
$ docker-compose ps
            Name                          Command               State          Ports        
--------------------------------------------------------------------------------------------
docker-compose-handson_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp 
docker-compose-handson_web_1   docker-php-entrypoint apac ...   Up      0.0.0.0:8200->80/tcp
```

### 補足1: Name

補足: `db` がサービス名、`docker-compose-handson_db_1` がコンテナ名です。
`db` サービスは `3306/tcp`, `33060/tcp` のポートが起動してます。

### 補足2: Command

`Command`に書かれてるコマンドが現在実行中、または最後に実行されたコマンドが表示されています。

### 補足3: State

コンテナのステータスです。
db, webサービスが起動(`State: Up`)していることを確認します。

### 補足4: Ports

- db
  - 3306: 従来のMySQLプロトコルポート
  - 33060: Xプロトコルと呼ばれるMySQLの新しい接続方式のプロトコルポート
- web
  - 0.0.0.0:8200->80: ホスト側の8200ポートへアクセスするとwebコンテナの80ポートへ

## MySQL 初期データ設定

dbコンテナのmysqlコマンドを実行してMySQLへログインします。

```
$ docker-compose exec db bash
$ mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE
```

テストデータを入れます。

```
create table shop.items (
  id int primary key auto_increment,
  name varchar(30) comment '商品名',
  stock int default 0 comment '在庫数'
) comment='商品テーブル';

INSERT INTO shop.items (name, stock) VALUE ("Apple", 10);
INSERT INTO shop.items (name, stock) VALUE ("Bad Apple", 1);
```

## 動作確認

- http://127.0.0.1:8200

ショップアプリがphpを実行してmysqlからデータの取得や更新が行えていればokです。

## さいごに

お疲れ様でした！
Docker Compose ハンズオンいかがでしたでしょうか。
コンテナをまとめて起動、停止できる `docker-compose` はとても便利ですね。
ボリュームやネットワークの設定も簡単に行えるようになりました。