体育会系 Docker Compose ハンズオン資料（2）


[体育会系 Docker Compose ハンズオン資料（1）](http://qiita.com/inokappa/private/14f731d383d266255961) の続きです。

## メニュー

### 注意

- 資料の見方
- 事前準備について
- 資料内で紹介する各種ツールのバージョンについて
- 後片付けはしっかりと

### 参考資料

- 参考 URL
- 参考書籍

### 4. Docker Compose で WordPress サイトを立ち上げてみよう

1. Docker Compose とは
2. 作成する環境について
3. Docker Compose のインストール
4. はじめての docker-compose.yml
5. WordPress の準備
6. WordPress を起動する
7. WordPress にアクセスする
8. WordPress を停止する
9. WordPress を再起動する
10. WordPress を削除する
11. 安心して下さい

### 5. (おまけ) スケールイン、スケールアウトを試してみよう

1. スケールイン・スケールアウト
2. スケールイン・スケールアウトを試してみる

### 6. (おまけ) データ用コンテナで作るちょっとしたファイルアップロードシステム

1. データ専用コンテナ
2. ファイルアップロードを試してみる

### 7. 最後に

1. Docker Compose を使うことで
2. ご不明な点があれば

***

## 注意

### 資料の見方

以下、実行するコマンドの表示です。

~~~sh:command
# コメントです

# ハンズオン内で実行するコマンドです（コピー＆ペーストで貼り付けて利用して下さい）
command "foo" "bar"
~~~

以下、出力例の表示です。

~~~sh:output
# コマンドの実行後の出力例です
~~~

上記に実行例と異なる出力を確認した場合にはお声がけ下さい。

### 事前準備について

- ハンズオンを円滑に進めるにあたって事前準備は出来るだけ行うようにして下さい

### 資料内で紹介する各種ツールのバージョンについて

資料内で紹介する各種ツールのバージョンは以下の通りです。

- OS

~~~sh:output
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"
~~~

- Docker Engine

~~~sh:output
$ docker version
Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:54:52 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:54:52 2016
 OS/Arch:      linux/amd64
~~~

- Docker Compose

~~~sh:output
$ docker-compose version
docker-compose version 1.6.2, build 4d72027
docker-py version: 1.7.2
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013
~~~

- WordPress

![2016031304.png](https://qiita-image-store.s3.amazonaws.com/0/87189/533944d7-a069-2d9c-89e4-4bf4c31627ca.png "2016031304.png")

WordPress 4.4.2 を利用します。

### 後片付けはしっかりと

本日作成した仮想マシンはハンズオン終了後、不要であれば削除しておきましょう。

***

## 参考資料

### 参考 URL

- [Docker ドキュメント日本語化プロジェクト](http://docs.docker.jp/)

### 参考書籍

- [プログラマのためのDocker教科書 インフラの基礎知識＆コードによる環境構築の自動化](http://www.shoeisha.co.jp/book/detail/9784798141022)

***

## 4. Docker Compose で WordPress サイトを立ち上げてみよう

### 4.1. Docker Compose とは

複数の Docker コンテナで構築されているアプリケーションを一つの YAML ファイルで管理出来るツールで、以下のような機能を提供します。

- Docker Compose コマンドを実行するだけで複数のコンテナの起動と停止等を管理することが出来る
- 起動するコンテナのイメージ、コマンド、ポート、ボリューム等設定を YAML ファイルで管理することが出来る
- YAML ファイルは Dockerfile と似ているので解りやすい

以下のようなイメージです。

![2016040604.png](https://qiita-image-store.s3.amazonaws.com/0/87189/ff625a58-7984-b575-9df9-3cd1599b57ef.png "2016040604.png")

尚、Docker Compose について詳細を知りたい場合には以下のドキュメントがとても参考になりますので目を通しておくと良いでしょう。

- http://docs.docker.jp/compose/toc.html


### 4.2 作成する環境について

以下のような構成の環境を作成します。

![2016031203.png](https://qiita-image-store.s3.amazonaws.com/0/87189/6218696a-6d37-c98b-e6ad-479dbac1b6c4.png "2016031203.png")


WordPress を動かすコンテナと MySQL を動かすコンテナそれぞれを個別に管理することも可能ですが、Docker Compose を利用することで、`docker-compose` コマンド一発で立ち上げることが出来ます。

### 4.3 Docker Compose のインストール

Docker Compose はワンバイナリで提供されており、以下のコマンドを実行してインストールします。

~~~sh:command
#
# docker-compose コマンドをダウンロードします
#
sudo sh -c 'curl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose'

#
# ダウンロードした docker-compose コマンドに実行権限を付与します
#
sudo chmod +x /usr/local/bin/docker-compose
~~~

以下のようにコマンドを実行して Docker Compose がインストールされていることを確認します。

~~~sh:command
ls -l /usr/local/bin/docker-compose
~~~

以下のように出力されることを確認します。

~~~sh:output
-rwxr-xr-x 1 root root 7929597 Mar 12 03:50 /usr/local/bin/docker-compose
~~~

以下のようにコマンドを実行して Docker Compose のバージョンを確認します。

~~~sh:command
docker-compose version
~~~

以下のように出力されることを確認します。

~~~sh:output
docker-compose version 1.6.2, build 4d72027
docker-py version: 1.7.2
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013
~~~

### 4.4. はじめての docker-compose.yml

#### 4.4.1. 作成済みの docker-compose.yml をダウンロードする

以下のようにコマンドを実行してハンズオン資料を `git clone` します。

~~~sh:command
cd ~/dockerfile/
git clone https://github.com/inokappa/handson-docker-compose-wordpress.git
~~~

#### 4.4.2. docker-compose.yml の内容を確認する

以下のように docker-compose.yml が含まれていることを確認します。

~~~sh:command
cd handson-docker-compose-wordpress
ls -l docker-compose.yml
~~~

以下のように出力されることを確認します。

~~~sh:output
lrwxrwxrwx 1 vagrant vagrant 21 Apr  6 14:02 docker-compose.yml -> docker-compose.yml.v2
~~~

以下のようにコマンドを実行して docker-compose.yml.v2 の内容を確認します。

~~~sh:command
cat docker-compose.yml
~~~

以下のように出力されることを確認します。

~~~yaml:ouput
version: "2"
services:
  web:
    build: .
    command: php -S 0.0.0.0:80 -t /code/WordPress/
    ports:
      - "80:80"
    depends_on:
      - db
    volumes:
      - .:/code
  db:
    image: mysql:5.6
    environment:
      MYSQL_DATABASE: wordpress      # WordPress で利用する MySQL のデータベース名を指定
      MYSQL_ROOT_PASSWORD: wordpress # MySQL の ROOT パスワードを指定
~~~

それぞれのキーは以下を意味しています。

| キー | 値 | 意味 |
|:---|:---|:---|
| version | "2" | Version 1 と Version 2 を指定可能(サポートされる Docker Version が異なる) |
| services | web / db | version キーと一緒にトップレベルで指定する |
| build | . | カレントディレクトリの Dockerfile を利用してビルドを行う |
| command | php -S 0.0.0.0:80 -t /code/WordPress/ | コンテナ起動時に実行するとコマンド |
| ports | "80:80" | 公開するポートを指定する("ホストポート:コンテナポート") |
| depends_on | db | サービス間の依存関係を指定する(上記の例では `web` サービスのコンテナが起動する前に `db` コンテナが起動します) |
| volumes | .:/code | 指定したパスをボリュームとしてマウントする("ホストディレクトリ:コンテナディレクトリ") |
| image | mysql:5.6 | コンテナイメージを指定 |
| environment | MYSQL_DATABASE: WordPress / MYSQL_ROOT_PASSWORD: WordPress | 環境変数を上書きする |

その他のキーや各キーの詳細は[こちら](http://docs.docker.jp/compose/compose-file.html)のページがとても参考になりますので、目を通しておくと良いでしょう。

#### 4.4.3. docker-compose.yml.v1 の内容を確認する

以下のように docker-compose.yml.v1 が含まれていることを確認します。

~~~sh:command
cd handson-docker-compose-wordpress
ls -l docker-compose.yml.v1
~~~

以下のように出力されることを確認します。

~~~sh:output
-rw-rw-r-- 1 vagrant vagrant 234 Apr  6 13:08 docker-compose.yml.v1
~~~

以下のようにコマンドを実行して docker-compose.yml.v2 の内容を確認します。

~~~sh:command
cat docker-compose.yml.v1
~~~

以下のように出力されることを確認します。

~~~yaml:ouput
web:
  build: .
  command: php -S 0.0.0.0:80 -t /code/wordpress/
  ports:
    - "80:80"
  links:
    - db
  volumes:
    - .:/code
db:
  image: mysql:5.6
  environment:
    MYSQL_DATABASE: wordpress      # WordPress で利用する MySQL のデータベース名を指定
    MYSQL_ROOT_PASSWORD: wordpress # MySQL の ROOT パスワードを指定
~~~

それぞれのキーは以下を意味しています。

| キー | 値 | 意味 |
|:---|:---|:---|
| web / db |  | トップレベルで指定する |
| build | . | カレントディレクトリの Dockerfile を利用してビルドを行う |
| command | php -S 0.0.0.0:80 -t /code/WordPress/ | コンテナ起動時に実行するとコマンド |
| ports | "80:80" | 公開するポートを指定する("ホストポート:コンテナポート") |
| links | db | Docker Link 機能を利用して接続するコンテナサービス名を指定(db:database のようにエイリアス名でも指定可) |
| volumes | .:/code | 指定したパスをボリュームとしてマウントする("ホストディレクトリ:コンテナディレクトリ") |
| image | mysql:5.6 | コンテナイメージを指定 |
| environment | MYSQL_DATABASE: WordPress / MYSQL_ROOT_PASSWORD: WordPress | 環境変数を上書きする |

その他のキーや各キーの詳細は[こちら](http://docs.docker.jp/compose/compose-file.html)のページがとても参考になりますので、目を通しておくと良いでしょう。

### 4.5. WordPress の準備

#### 4.5.1. WordPress のダウンロードと展開

以下のようにコマンドを実行して WordPress をダウロードします。

~~~sh:command
cd ~/dockerfile/handson-docker-compose-wordpress
wget https://ja.wordpress.org/wordpress-4.4.2-ja.tar.gz
tar zxvf wordpress-4.4.2-ja.tar.gz
rm wordpress-4.4.2-ja.tar.gz
~~~

以下のように WordPress がダウンロードされ、展開されていることを確認します。

~~~sh:command
ls -l .
~~~

以下のように出力されることを確認します。

~~~sh:output
total 16
lrwxrwxrwx 1 vagrant vagrant   21 Apr  6 14:10 docker-compose.yml -> docker-compose.yml.v2
-rw-rw-r-- 1 vagrant vagrant  234 Apr  6 14:10 docker-compose.yml.v1
-rw-rw-r-- 1 vagrant vagrant  290 Apr  6 14:10 docker-compose.yml.v2
-rw-rw-r-- 1 vagrant vagrant  107 Apr  6 14:10 Dockerfile
drwxr-xr-x 5 vagrant vagrant 4096 Feb  3 12:38 wordpress
~~~

#### 4.5.2. WordPress の設定修正(wp-config.php の編集)

以下のようにコマンドを実行して WordPress の wp-config.php を編集します。

~~~sh:command
cd ~/dockerfile/handson-docker-compose-wordpress
cd wordpress/
cp wp-config-sample.php wp-config.php
vim wp-config.php
~~~

以下の項目を変更します。

- DB_NAME
- DB_USER
- DB_PASSWORD
- DB_HOST

変更後は以下のような内容となります。

~~~sh:output
/** WordPress のためのデータベース名 */
define('DB_NAME', 'wordpress');

/** MySQL データベースのユーザー名 */
define('DB_USER', 'root');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'wordpress');

/** MySQL のホスト名 */
define('DB_HOST', 'db:3306');
~~~

編集したら保存して wp-config.php を閉じます。

#### 4.5.3. Dockerfile の準備

WordPress 用コンテナイメージを作成する為に Dockerfile を準備します。
以下のようにコマンドを実行して Dockerfile が含まれていることを確認します。

~~~sh:command
cd ~/dockerfile/handson-docker-compose-wordpress
ls -l Dockerfile
~~~

以下のように出力されることを確認します。

~~~sh:output
-rw-rw-r-- 1 vagrant vagrant 11 Mar 12 01:14 Dockerfile
~~~

以下のようにコマンドを実行して Dockerfile の内容を確認します。

~~~sh:command
cat Dockerfile
~~~

以下のように出力されることを確認します。

~~~sh:output
# オフィシャルの php イメージを利用する
FROM php:5.6-apache

# apt-get update を実行する
# docker-php-ext-install スクリプトを利用して pdo_mysql mysqli mbstring をインストールする
RUN apt-get update && \
  docker-php-ext-install pdo_mysql mysqli mbstring
  
# カレントディレクトリのファイルをコンテナの /code 以下に追加する
ADD . /code
~~~

### 4.6. WordPress を起動する

ここまで準備が出来たらいよいよ docker-compose を利用して WordPress を起動します。

#### 4.6.1. docker-compose up

以下のようにコマンドを実行して docker-compose を利用して WordPress を起動します。

~~~sh:command
cd ~/dockerfile/handson-docker-compose-wordpress
docker-compose up

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 up
~~~

以下のように出力されることを確認します。

~~~sh:output
Creating network "wp_default" with the default driver
Pulling db (mysql:5.6)...
5.6: Pulling from library/mysql
fdd5d7827f33: Already exists

（略）

db_1  | 2016-03-13 02:44:29 1 [Warning] 'proxies_priv' entry '@ root@f607ab279591' ignored in --skip-name-resolve mode.
db_1  | 2016-03-13 02:44:29 1 [Note] Event Scheduler: Loaded 0 events
db_1  | 2016-03-13 02:44:29 1 [Note] mysqld: ready for connections.
db_1  | Version: '5.6.29'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
~~~

WordPress コンテナのビルドと MySQL コンテナの取得と起動がしていることが判ります。

#### 4.6.2. docker-compose up をデタッチモードで起動する

一度、以下のように `Ctrl + c` を押して WordPress コンテナと MySQL コンテナを終了します。

~~~sh:output
db_1  | Version: '5.6.29'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

# Ctrl + c を押す
^CGracefully stopping... (press Ctrl+C again to force)
Stopping wp_web_1 ... done
Stopping wp_db_1 ... done
~~~

改めて、以下のように `-d` オプションを付与して `docker-compose up` を実行します。

~~~sh:command
docker-compose up -d

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 up -d
~~~

以下のように出力されることを確認します。

~~~sh:output
Starting wp_db_1
Starting wp_web_1
~~~

以下のようにコマンドを実行して WordPress コンテナと MySQL コンテナが起動していることを確認します。

~~~sh:command
docker-compose ps

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 ps
~~~

以下のように出力されることを確認します。

~~~sh:output
  Name                Command               State         Ports        
----------------------------------------------------------------------
wp_db_1    /entrypoint.sh mysqld            Up      3306/tcp           
wp_web_1   php -S 0.0.0.0:80 -t /code ...   Up      0.0.0.0:80->80/tcp 
~~~

以下のようにコマンドを実行して、同様に WordPress コンテナと MySQL コンテナが起動していることを確認します。

~~~sh:command
docker ps
~~~

以下のように出力されることを確認します。

~~~sh:output
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
b44387041f42        wp_web              "php -S 0.0.0.0:80 -t"   5 hours ago         Up About a minute   0.0.0.0:80->80/tcp   wp_web_1
f607ab279591        mysql:5.6           "/entrypoint.sh mysql"   6 hours ago         Up About a minute   3306/tcp             wp_db_1
~~~

### 4.7. WordPress にアクセスする

ブラウザを利用して WordPress にアクセスしましょう。

![2016031301.png](https://qiita-image-store.s3.amazonaws.com/0/87189/a051740b-7451-2e79-8d09-cb469e749842.png "2016031301.png")

上図のように出力されればシメたものです。

必要事項を入力して WordPress のインストールを進めましょう。必要事項を記入してインストールを進めた後、ログインすると以下のように表示されることを確認します。

![2016031302.png](https://qiita-image-store.s3.amazonaws.com/0/87189/75ca82d6-1e22-e9ce-b7b7-554b94e2ce67.png "2016031302.png")

記事を作成して公開してみましょう。以下のように記事を確認することが出来れば大変お疲れ様でした。

![2016031303.png](https://qiita-image-store.s3.amazonaws.com/0/87189/e4f7d415-9407-391c-f841-d6f6890ab017.png "2016031303.png")

しかし、ハンズオンはまだまだ続きます。

### 4.8. WordPress を停止する

以下のようにコマンドを実行して WordPress コンテナと MySQL コンテナを停止します。

~~~sh:command
docker-compose stop

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 stop
~~~

以下のように出力されることを確認します。

~~~sh:output
Stopping wp_web_1 ... done
Stopping wp_db_1 ... done
~~~

以下のようにコマンドを実行して、WordPress コンテナと MySQL コンテナが起動していることを確認します。

~~~sh:command
docker-compose ps

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 ps
~~~

以下のように出力されることを確認します。

~~~sh:output
  Name                Command                State     Ports 
------------------------------------------------------------
wp_db_1    /entrypoint.sh mysqld            Exit 0           
wp_web_1   php -S 0.0.0.0:80 -t /code ...   Exit 137 
~~~

ブラウザでアクセスして WordPress が表示されないことも確認しましょう。

### 4.9 WordPress を再起動する

再度、WordPress を起動する為に以下のようにコマンドを実行します。

~~~sh:command
docker-compose start

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 start
~~~

以下のように出力されることを確認します。

~~~sh:output
Starting wp_db_1
Starting wp_web_1
~~~

改めて、ブラウザで WordPress にアクセスしてみましょう。

![2016031303.png](https://qiita-image-store.s3.amazonaws.com/0/87189/813cc98c-feb2-2ea1-4e15-e0ccf0d95277.png "2016031303.png")

お疲れ様でした。

### 4.10. WordPress を削除する

ひとしきり WordPress を体験したら以下のコマンドを実行して WordPress を停止して削除します。

~~~sh:command
# WordPress を停止する
docker-compose stop

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 stop
~~~

以下のように出力されることを確認します。

~~~sh:output
Stopping wp_web_1 ... done
Stopping wp_db_1 ... done
~~~

以下のコマンドを実行して WordPress を削除します。

~~~sh:command
docker-compose rm

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 rm
~~~

以下のように出力されることを確認します。

~~~sh:output
Going to remove wp_web_1, wp_db_1
# 削除しても良いなら y を入力する(サ・ヨ・ウ・ナ・ラ)
Are you sure? [yN] y
Removing wp_web_1 ... done
Removing wp_db_1 ... done
~~~

本当にお疲れ様でした。本日のハンズオンはここで終了です。

### 安心して下さい

今日のハンズオンを明日にでも職場で再現したいと思った貴方、安心して下さい。仮想マシンさえ削除しなければ、以下のコマンドを実行するだけで WordPress は改めて貴方の手元に蘇ります。（但し、投稿した記事は蘇りません...）

~~~sh:command
docker-compose up

#
# docker-compose.yml.v1 で起動する場合には以下のように起動します
#
docker-compose -f docker-compose.yml.v1 up
~~~

尚、同じ仮想マシンで WordPress 環境が蘇らない場合には以下のようにコンテナイメージを削除することで WordPress 環境を復活させることが出来ます。

~~~sh:command
docker rmi -f wp_web
docker rmi -f mysql
~~~

docker-compose.yml と Dockerfile さえあれば、仮想マシンを選ばずに環境を再現出来るのも Docker Compose の強みだと思います。是非、試してみましょう。

***

## 5. (おまけ) スケールイン、スケールアウトを試してみよう

### 5.1. スケールイン、スケールアウト

Docker Compose では `scale` オプションが利用出来ます。これは下図ように単一のホスト内で指定したサービスのコンテナの数を増減することが出来る機能です。

![2016031502.png](https://qiita-image-store.s3.amazonaws.com/0/87189/a02a9e9a-e7d6-02e2-60dd-a4f3eae3c85f.png "2016031502.png")

### 5.2. スケールイン、スケールアウトを試してみる

#### 5.2.1. docker-compose.yml と Dockerfile を取得する

以下のように GitHub のリポジトリからプロジェクト一式を適当なディレクトリに clone します。

~~~sh:command
cd ~/dockerfile/
git clone https://github.com/inokappa/handson-docker-compose-scale.git
~~~

以下のように出力されることを確認します。

~~~sh:output
Cloning into 'sample-docker-compose-scale'...
remote: Counting objects: 28, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 28 (delta 8), reused 25 (delta 5), pack-reused 0
Unpacking objects: 100% (28/28), done.
Checking connectivity... done.
~~~

#### 5.2.2. 環境を起動する

以下のようにコマンドを実行してデモ環境を起動します。

~~~sh:command
cd ~/dockerfile/handson-docker-compose-scale
./_demo.sh
~~~

以下のように出力されることを確認します。（コンテナのビルドが走りますので暫くお待ち下さい...）

~~~sh:command
Successfully built 974b57377b7c
Creating sampledockercomposescale_app_1
Creating sampledockercomposescale_consul_server_1
Creating sampledockercomposescale_registrator_1
Creating sampledockercomposescale_haproxy_1
~~~

以下のようにコマンドを実行して起動しているコンテナの状態を確認します。

~~~sh:ommand
docker-compose -f docker-compose.yml.v1 ps
~~~

以下のように出力されることを確認します。

~~~sh:output
                  Name                                Command               State                                            Ports                                           
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sampledockercomposescale_app_1             sh run-app.sh                    Up      0.0.0.0:32774->4567/tcp                                                                  
sampledockercomposescale_consul_server_1   /bin/consul agent -server  ...   Up      8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 8400/tcp, 8500/tcp, 8600/tcp, 8600/udp 
sampledockercomposescale_haproxy_1         /bin/bash /root/run-haproxy.sh   Up      0.0.0.0:80->80/tcp                                                                       
sampledockercomposescale_registrator_1     /bin/registrator --interna ...   Up 
~~~

4 つのコンテナが起動していることを確認します。図にすると以下のようなイメージの環境で構築されています。

![2016031501.png](https://qiita-image-store.s3.amazonaws.com/0/87189/dfac12d7-0fd7-0a2a-1dbb-2c37918d814c.png "2016031501.png")

更に以下のようにブラウザでアクセス出来ることを確認します。

![2016031401.png](https://qiita-image-store.s3.amazonaws.com/0/87189/04683cd4-65f5-c348-b8ea-51c3a48ea5f9.png "2016031401.png")

アプリケーションコンテナのホスト名が表示されている（だけ）ですが...

#### 5.2.3. スケールイン、スケールアウトを試してみる

以下のようにコマンドを実行してスケールイン、スケールアウトを行います。

- スケールアウト

~~~sh:command
docker-compose -f docker-compose.yml.v1 scale app=2
~~~

以下のように出力されることを確認します。

~~~sh:output
Creating and starting 2 ... done
~~~

以下のようにスケールアウト(アプリケーションコンテナが追加)されたことを確認することが出来ます。

~~~sh:command
docker-compose -f docker-compose.yml.v1 ps app
~~~

以下のように出力されることを確認します。

~~~sh:output
             Name                   Command      State            Ports          
--------------------------------------------------------------------------------
sampledockercomposescale_app_1   sh run-app.sh   Up      0.0.0.0:32774->4567/tcp 
sampledockercomposescale_app_2   sh run-app.sh   Up      0.0.0.0:32775->4567/tcp 
~~~

以下のように `curl` を利用してブラウザと同様に確認することが出来ます。

~~~sh:command
curl localhost/hostname
~~~

以下のように出力されることを確認します。

~~~sh:output
# 一回目の実行結果
$ curl localhost/hostname
a0aaa121c96e
# 二回目の実行結果
$ curl localhost/hostname
068962497d6d
~~~

- スケールイン

~~~sh:command
docker-compose -f docker-compose.yml.v1 scale app=1
~~~

以下のように出力されることを確認します。

~~~sh:output
Stopping and removing sampledockercomposescale_app_2 ... done
~~~


以下のようにスケールイン(アプリケーションコンテナが削除)されたことを確認することが出来ます。

~~~sh:command
docker-compose -f docker-compose.yml.v1 ps app 
~~~

以下のように出力されることを確認します。

~~~sh:output
             Name                   Command      State            Ports          
--------------------------------------------------------------------------------
sampledockercomposescale_app_1   sh run-app.sh   Up      0.0.0.0:32774->4567/tcp
~~~

以下のように `curl` を利用してブラウザと同様に確認することが出来ます。

~~~sh:command
curl localhost/hostname
~~~

以下のように出力されることを確認します。

~~~sh:output
# 一回目の実行結果
$ curl localhost/hostname
a0aaa121c96e
# 二回目の実行結果
$ curl localhost/hostname
a0aaa121c96e
~~~

アプリケーションコンテナが削除されたので何度アクセスしても同じホスト名しか出力されないことを確認します。

#### 5.2.4. デモ環境の停止

以下のようにコマンドを実行してデモ環境を停止します。

~~~sh:command
docker-compose -f docker-compose.yml.v1 stop
~~~

以下のように出力されることを確認します。

~~~sh:output
Stopping handsondockercomposescale_haproxy_1 ... done
Stopping handsondockercomposescale_registrator_1 ... done
Stopping handsondockercomposescale_consul_server_1 ... done
Stopping handsondockercomposescale_app_1 ... done
~~~

更に以下のようにコマンドを実行してデモ環境を破棄します。

~~~sh:command
docker-compose -f docker-compose.yml.v1 rm -f
~~~

以下のように出力されることを確認します。

~~~sh:output
Going to remove handsondockercomposescale_haproxy_1, handsondockercomposescale_registrator_1, handsondockercomposescale_consul_server_1, handsondockercomposescale_app_1
Removing handsondockercomposescale_haproxy_1 ... doneRemoving handsondockercomposescale_registrator_1 ... done
Removing handsondockercomposescale_consul_server_1 ... done
Removing handsondockercomposescale_app_1 ... done
~~~

以下のように実行してデモ環境のコンテナが破棄されていることを確認します。

~~~sh:command
docker-compose -f docker-compose.yml.v1 rm -f
~~~

以下のように出力されることを確認します。

~~~sh:command
Name   Command   State   Ports 
------------------------------
~~~

次のおまけを試す場合には必ずデモ環境は破棄しておきましょう。

***

## 6. (おまけ) データ用コンテナで作るちょっとしたファイルアップロードシステム

### 6.1 データ用コンテナ

#### 6.1.1. データ用コンテナ

Docker ではデータを保存するだけのコンテナを作成して、下図のように他のコンテナのデータ領域として利用することが出来ます。尚、データ用コンテナは OS イメージのコンテナや busybox コンテナを利用して作成することが出来ます。

![2016033103.png](https://qiita-image-store.s3.amazonaws.com/0/87189/5896adb8-0d36-646b-d395-be863e3e1913.png "2016033103.png")

今回は下図のようなファイルアップロードシステムにおいて、アップロードしたファイルを保存する為にアプリケーションサーバーにマウントして利用します。

![2016033104.png](https://qiita-image-store.s3.amazonaws.com/0/87189/421e616e-3f8c-a7b9-5028-a0ab01114196.png "2016033104.png")

また、アプリケーションサーバーをスケールアウトさせて複数のアプリケーションコンテナから NFS のように（あくまでも擬似的に）利用してみたいと思います。

### 6.2 ファイルアップロードを試してみる

#### 6.2.1. docker-compose.yml と Dockerfile を取得する

以下のように GitHub のリポジトリからプロジェクト一式を適当なディレクトリに clone します。

~~~sh:command
cd ~/dockerfile/
git clone https://github.com/inokappa/handson-docker-compose-storage.git
~~~

以下のように出力されることを確認します。

~~~sh:output
Cloning into 'handson-docker-compose-storage'...
remote: Counting objects: 42, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 42 (delta 6), reused 42 (delta 6), pack-reused 0
Unpacking objects: 100% (42/42), done.
Checking connectivity... done.
~~~

#### 6.2.2. 環境を起動する

以下のようにコマンドを実行してデモ環境を起動します。

~~~sh:command
cd ~/dockerfile/handson-docker-compose-storage
./_demo.sh
~~~

以下のように出力されることを確認します。（コンテナのビルドが走りますので暫くお待ち下さい...）

~~~sh:command
(略)

Successfully built 8ea22ce2162b
Creating handsondockercomposestorage_storage_1
Creating handsondockercomposestorage_app_1
Creating handsondockercomposestorage_consul_server_1
Creating handsondockercomposestorage_registrator_1
Creating handsondockercomposestorage_haproxy_1
~~~

以下のようにコマンドを実行して起動しているコンテナの状態を確認します。

~~~sh:ommand
docker-compose -f docker-compose.yml.v1 ps
~~~

以下のように出力されることを確認します。

~~~sh:output
               Name                               Command                               State                                Ports                
-------------------------------------------------------------------------------------------------------------------------------------------------
handsondockercomposestorage_app_1    sh run-app.sh                        Up                                   0.0.0.0:32832->4567/tcp            
handsondockercomposestorage_consul   /bin/consul agent -server  ...       Up                                   8300/tcp, 8301/tcp, 8301/udp,      
_server_1                                                                                                      8302/tcp, 8302/udp, 8400/tcp,      
                                                                                                               8500/tcp, 8600/tcp, 8600/udp       
handsondockercomposestorage_haprox   /docker-entrypoint.sh /bin ...       Up                                   0.0.0.0:80->80/tcp                 
y_1                                                                                                                                               
handsondockercomposestorage_regist   /bin/registrator --interna ...       Up                                                                      
rator_1                                                                                                                                           
handsondockercomposestorage_storag   tail -f /dev/null                    Up                                                                      
e_1  
~~~

5 つのコンテナが起動していることを確認します。図にすると以下のようなイメージの環境で構築されています。

更に以下のようにブラウザでアクセスすると起動中のコンテナ一覧を確認することが出来ます。

![2016033001.png](https://qiita-image-store.s3.amazonaws.com/0/87189/b93f77ae-a0ee-ca1c-0e63-45a46dedd43d.png "2016033001.png")

#### 6.2.3. ファイルアップロードして確認する

以下のように Uploader ページにアクセスしてファイルのアップロードを行います。

![2016033002.png](https://qiita-image-store.s3.amazonaws.com/0/87189/576ef3e0-7c9e-60fc-9e54-1134f65d5b6b.png "2016033002.png")


適当な画像ファイルを選択してアップロードします。

![2016033003.png](https://qiita-image-store.s3.amazonaws.com/0/87189/a95f2746-cb4a-39d8-8cd3-c8b4c9d241af.png "2016033003.png")

アップロード完了ページからファイルのリンクをクリックして画像を表示してみましょう。

![2016033004.png](https://qiita-image-store.s3.amazonaws.com/0/87189/523af49e-7cc8-f1d6-c033-2bfd3e3c56db.png "2016033004.png")

ブラウザバックを利用して前のページに戻った後、Go to Images page をクリックして画像一覧ページにもアクセスしてみます。

![2016033005.png](https://qiita-image-store.s3.amazonaws.com/0/87189/8dd0f03c-eec4-f2f5-32d7-d9e9dea70612.png "2016033005.png")

#### 6.2.4. データ用コンテナにファイルが保存されていることを確認する

以下のようにコマンドを実行してデータ用コンテナに前のステップでアップロードしたファイルが保存されていることを確認します。

~~~sh:command
docker exec -t -i handsondockercomposestorage_storage_1 ls -l /mnt/data
~~~

以下のように出力されることを確認します。

~~~sh:output
total 4
-rw-r--r-- 1 root root 1539 Mar 30 14:29 46246da8fbae_General_AWScloud.png
~~~

#### 6.2.5. アプリケーションコンテナをスケールイン、スケールアウトしてファイルアップロードを試してみる

以下のようにコマンドを実行してスケールイン、スケールアウトを行います。

- スケールアウト

~~~sh:command
docker-compose -f docker-compose.yml.v1 scale app=2
~~~

以下のように出力されることを確認します。

~~~sh:output
Creating and starting 2 ... done
~~~

以下のようにスケールアウト(アプリケーションコンテナが追加)されたことを確認することが出来ます。

~~~sh:command
docker-compose -f docker-compose.yml.v1 ps app
~~~

以下のように出力されることを確認します。

~~~sh:output
              Name                     Command      State            Ports          
-----------------------------------------------------------------------------------
handsondockercomposestorage_app_1   sh run-app.sh   Up      0.0.0.0:32832->4567/tcp 
handsondockercomposestorage_app_2   sh run-app.sh   Up      0.0.0.0:32833->4567/tcp 
~~~

以下のようにブラウザでアクセスするとコンテナ一覧に追加されたアプリケーションコンテナを確認することが出来ます。

![2016033006.png](https://qiita-image-store.s3.amazonaws.com/0/87189/e536e5da-1bbb-0bca-d78b-1916d33c7292.png "2016033006.png")

6.2.3. と同様にファイルのアップロードを試してみましょう。

![2016033102.png](https://qiita-image-store.s3.amazonaws.com/0/87189/ff4e4388-6fc5-0cc1-001f-3d999ab1bf79.png "2016033102.png")

また、データ用コンテナにファイルが保存されているかも確認しましょう。

~~~sh:command
docker exec -t -i handsondockercomposestorage_storage_1 ls -l /mnt/data
~~~

ファイルが保存されていることを確認しましょう。

~~~sh:output
total 8
-rw-r--r-- 1 root root 1539 Mar 30 14:29 46246da8fbae_General_AWScloud.png
-rw-r--r-- 1 root root  660 Mar 30 22:28 b2d1025534dd_General_AWSManagementConsole.png
~~~

- スケールイン

~~~sh:command
docker-compose -f docker-compose.yml.v1 scale app=1
~~~

以下のように出力されることを確認します。

~~~sh:output
Stopping and removing handsondockercomposestorage_app_2 ... done
~~~


以下のようにスケールイン(アプリケーションコンテナが削除)されたことを確認することが出来ます。

~~~sh:command
docker-compose -f docker-compose.yml.v1 ps app 
~~~

以下のように出力されることを確認します。

~~~sh:output
              Name                     Command      State            Ports          
-----------------------------------------------------------------------------------
handsondockercomposestorage_app_1   sh run-app.sh   Up      0.0.0.0:32832->4567/tcp 
~~~

以下のようにブラウザでアクセスするとコンテナ一覧を確認することが出来ます。

![2016033101.png](https://qiita-image-store.s3.amazonaws.com/0/87189/bedbf7c2-ba28-c095-4da0-46bdcde1c62c.png "2016033101.png")

***

## 7. 最後に

### 7.1. Docker Compose を使うことで

複数のコンテナを利用したアプリケーション環境をコマンド一発で起動、破棄、再起動することが出来ますので、以下のような用途に適していると考えます。

- 開発環境
- 自動テスト環境
- デモ環境

本番環境への導入については Docker Compose だけだと、単一のホストへのデプロイに限定されていることもありますので、お薦めすることは(個人的に)出来ません。但し、Docker Swarm 等の Docker ホストのクラスタツールを利用することで本番環境への導入も可能ではないかと考えています。

### 7.2. ご不明な点があれば

お気軽にお声がけ頂ければ幸いです。一緒に課題解決していきましょう。

今日のハンズオンが皆さんの明日からのお仕事や学習に少しでもお役に立てれば幸いです。