MacにDocker - Docker Compose

[MacにDocker](http://qiita.com/sakasa/items/d32f2cab50a597b5eb50)
ここの子ページ的な

#バージョン
```bash:バージョン
$ docker --version
Docker version 1.13.0, build 49bf474
$ docker-compose --version
docker-compose version 1.10.0, build 4bd6f1a
$ docker-machine --version
docker-machine version 0.9.0, build 15fd4c7
```

#Dockerコンテナ間のリンク
Docker Composeの前に、コンテナ間を連携するのに必要なリンク機能について。

複数のコンテナを連携して処理を行う場合に、Dockerのリンク機能を使います。（例としては、[Web3層アーキテクチャ](http://e-words.jp/w/3%E9%9A%8E%E5%B1%A4%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0.html)のようなシステムを構築する場合に使用）

```bash:リンク設定
$ docker run --link 接続したいコンテナ名:エイリアス名 イメージ名 実行コマンド
```

※このリンク機能は同一ホストマシン上で起動しているコンテナ間でしかアクセスできません。

###CentOSのアプリケーションサーバとPostgreSQLのDBサーバをリンクする場合

```bash:名前を指定してPostgreSQLコンテナを起動
$ docker run -d --name dbserver postgres

$ docker ps -a
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                    PORTS                  NAMES
238bf1199031        postgres                   "/docker-entrypoin..."   54 seconds ago      Up 51 seconds             5432/tcp               dbserver
```

```bash:PostgreSQLコンテナへリンク設定してCentOSのアプリケーションサーバを起動
$ docker run -it --name appserver --link dbserver:pg centos /bin/bash
[root@0a522bca0879 /]#
```

```bash:「appserver」の環境変数に「dbserver」の情報が設定されます。
[root@0a522bca0879 /]# set |grep PG
PG_ENV_GOSU_VERSION=1.7
PG_ENV_LANG=en_US.utf8
PG_ENV_PGDATA=/var/lib/postgresql/data
PG_ENV_PG_MAJOR=9.6
PG_ENV_PG_VERSION=9.6.1-2.pgdg80+1
PG_ENV_no_proxy='*.local, 169.254/16'
PG_NAME=/appserver/pg
PG_PORT=tcp://172.17.0.2:5432
PG_PORT_5432_TCP=tcp://172.17.0.2:5432
PG_PORT_5432_TCP_ADDR=172.17.0.2
PG_PORT_5432_TCP_PORT=5432
PG_PORT_5432_TCP_PROTO=tcp
```

```bash:「appserver」のhostsファイルに「dbserver」の情報が書き込まれます。
[root@0a522bca0879 /]# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	pg 238bf1199031 dbserver # 「dbserver」の情報
172.17.0.3	0a522bca0879
```

```bash:「appserver」から「dbserver」にping
[root@0a522bca0879 /]# ping pg
PING pg (172.17.0.2) 56(84) bytes of data.
64 bytes from pg (172.17.0.2): icmp_seq=1 ttl=64 time=0.239 ms
64 bytes from pg (172.17.0.2): icmp_seq=2 ttl=64 time=0.124 ms
```

#Docker Compose って
複数のコンテナをまとめて管理するためのツール。
「docker-compose.yml」というファイルにコンテナの定義情報を定義して、同一ホスト所の複数コンテナを一括管理します。


#構成ファイル（docker-compose.yml）の構文

##形式
[YAML形式](https://ja.wikipedia.org/wiki/YAML)

##image/build：ベースイメージの指定

webserverというコンテナ名のベースイメージを「CentOS」に指定

```yaml:Dockerイメージを指定
webserver:
  image: centos
```

```yaml:Dockerfileからビルド
webserver:
  build: . # Dockerfileのパスを指定
```

##コンテナの生成

Dockerfileを使用してdocker-composeを起動します。

```bash:Dockerfile
$ cat Dockerfile
FROM centos 
#centosのベースイメージを指定しただけ
```

```bash:docker-compose.yml
$ cat docker-compose.yml
webserver:
  build: .
```

```bash:ファイル構成
$ ls
Dockerfile		docker-compose.yml
```

```bash:コンテナの生成
$ docker-compose up
Creating dockercomposetest_webserver_1
Attaching to dockercomposetest_webserver_1
dockercomposetest_webserver_1 exited with code 0
```

```bash:コンテナの確認
$ docker ps -a
CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS                      PORTS               NAMES
312218ab567e        dockercomposetest_webserver   "/bin/bash"         26 seconds ago      Exited (0) 24 seconds ago                       dockercomposetest_webserver_1
```

##command：コンテナ内で動かすコマンド

```yaml:構文
command: /bin/bash
```
※ベースイメージで指定されている場合は、そのコマンドを上書きします。


##links/external_links：コンテナ間リンク連携

```yaml:構文
links:
  - dbserver
  - dbserver:mysql #エイリアス名をつけたいときは「コンテナ名：エイリアス名」で指定
```

同一のdocker-compose.ymlに定義のないコンテナとリンク機能で連携したい場合は、external_linksを使用します。（起動済みのコンテナを使用する場合など）

```yaml:構文
external_links:
  - redis
```

##ports/expose：コンテナ間通信

・ports
　コンテナが公開するポートを指定。
　「ホストマシンのポート:コンテナのポート」

```yaml:構文
ports:
  - "8000:80"
# YAMLはxx:yyを時刻として扱うので、ポート番号はダブルクォートで囲み、文字列として指定する
```

・expose
　ホストマシンへは公開せず、リンク機能で連携するコンテナのみに公開する場合に使用。

```yaml:構文
expose:
  - "8000"
```

##volumes/volumes_from

・volumes
　コンテナにボリュームをマウント。

```yaml:構文
volumes:
  - /var/www
  - tmp/:/var/tmp
  - config/:/ets/config:ro
# ホスト側でマウントするパスを指定する場合「ホストのパス:コンテナのパス」で指定する
# 後ろにroを指定すると、読み取り専用でマウントする
```

・volumes_from
　別のコンテナからすべてのボリュームをマウント

```yaml:構文
volumes_from:
  - log
# logという名前のコンテナにすべてのボリュームのマウント指定
```

##environment：コンテナの環境変数指定

```yaml:構文
# 配列形式で指定
environment:
  - LANG=ja_JP.utf8
  - HOGE=fuga

# ハッシュ形式で指定
environment:
  LANG: ja_JP.utf8
  HOGE: huga

# 外部ファイルから読み込み
environment: envfile # ファイルパス（ファイル名）を指定

# 外部ファイルから読み込み（複数指定）
environment:
  - ./env１
  - /etc/config/env2
```

```bash:envfile
$ cat envfile
LANG=ja_JP.utf8
HOGE=fuga
```

## container_name/labels：コンテナの情報設定

```yaml:構文
# 「webserver」という名前で定義したコンテナに「mycontainer」という名前をつける
container_name: mycontainer

# コンテナにラベルを付ける（配列形式）
labels:
  - コンテナA=web
  - コンテナB=db

# コンテナにラベルを付ける（ハッシュ形式）
labels:
  - コンテナA: web
  - コンテナB: db
```

#Docker Composeコマンド

##up：複数コンテナの生成

作成したdocker-compose.ymlを元に、複数のコンテナの起動/生成を行います。

```bash:構文
$ docker-compose up [オプション] [サービス名]
```

```bash:バックグラウンドで起動
$ docker-compose up -d
```

```bash:カレントディレクトリ以外のdocker-compose.ymlを指定して起動
$ docker-compose -f ./compose/docker-compose.yml up
```

「`Ctrl`+`c`」で実行しているコンテナを停止します。

##scale：生成するコンテナ数の指定

```bash:構文
$ docker-compose scale [サービス名=数]
```

サービス名「webserver」のコンテナを１０個、サービス名「dbserver」のコンテナを２個起動する場合

```bash:コンテナ数を指定
$ docker-compose scale webserver=10 dbserver=2
```

##ps：複数コンテナの確認

複数コンテナの一覧表示を行います。

```bash:構文
$ docker-compose ps [オプション] [サービス名]
```

```bash:コンテナIDのみを確認
$ docker-compose ps -q
```

##logs：ログ確認

コンテナのログを確認します。

```bash:構文
$ docker-compose logs [オプション] [サービス名]
```

##run：コマンド実行

```bash:構文
$ docker-compose run [オプション] [サービス名] [コマンド]
```

サービス名「webserver」のコンテナに`/bin/bash`を実行する場合

```bash:webserveに/bin/bash
$ docker-compose run webserver /bin/bash
root@5ef57c43a905:/#
```

##start/stop/restart：起動/停止/再起動

```bash:構文
# 起動
$ docker-compose start [サービス名]

# 停止
$ docker-compose stop [サービス名]

# 再起動
$ docker-compose restart [サービス名]
```

```bash:指定したコンテナのみを停止
$ docker-compose stop dbserver
```

##kill：強制停止

```bash:構文
$ docker-compose kill [オプション]
```

オプション無しの場合、コンテナにシグナル「SIGKILL」が送信され、プロセスが強制停止します。

シグナル「SIGINT」（キーボード割り込み：「`Ctrl`+`c`」）を送信する場合

```bash:Ctrl+cを送信
$ docker-compose kill -s SIGINT
```

##rm：削除

複数コンテナを削除します。

```bash:構文
$ docker-compose rm [オプション] [サービス名]
```

#WordPressシステム構築

##構成

- webサーバコンテナ
- dbサーバコンテナ
- データ専用コンテナ

##データ専用コンテナの作成

データ専用コンテナに[BusyBox](https://ja.wikipedia.org/wiki/BusyBox)を使用します。

```bash:Dockerfile.dataserver
# Dockerイメージ
FROM busybox

# データボリューム
VOLUME /var/lib/mysql
```

```bash:コンテナの生成
# イメージを作成
$ docker build -t dataserver -f Dockerfile.dataserver .
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM busybox
latest: Pulling from library/busybox
4b0bc1c4050b: Pull complete
Digest: sha256:817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e
Status: Downloaded newer image for busybox:latest
 ---> 7968321274dc
Step 2/2 : VOLUME /var/lib/mysql
 ---> Running in 0d0a53133dee
 ---> 02b98d920397
Removing intermediate container 0d0a53133dee
Successfully built 02b98d920397

# イメージの確認
$ docker images dataserver
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
dataserver          latest              02b98d920397        26 minutes ago      1.11 MB

# コンテナの起動
$ docker run -it --name dataserver dataserver
/ # exit

# コンテナ確認
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
4188faef2128        dataserver          "sh"                     26 minutes ago      Exited (0) 25 seconds ago                       dataserver
```

##webサーバ、dbサーバコンテナの作成

webサーバにwordpressのイメージ、dbサーバにmysqlのイメージを使用します。

```yml:docker-compose-wordpress.yml
# webサーバ
webserver:
  image: wordpress

  # ポート転送設定
  ports:
    - "80:80"

  # webサーバからdbサーバにコンテナ間リンクを指定します
  links:
    - "dbserver:mysql"

# dbサーバ
dbserver:
  image: mysql

  # データ保存先にデータ専用コンテナを指定します
  volumes_from:
    - dataserver

  # 環境変数の設定
  environment:
    MYSQL_ROOT_PASSWORD: password
```

```bash:
# コンテナの起動
$ docker-compose -f ./docker-compose-wordpress.yml up -d

# 確認
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                NAMES
ccbcfd423b49        wordpress           "docker-entrypoint..."   27 minutes ago      Up About a minute           0.0.0.0:80->80/tcp   wordpress_webserver_1
f4c629a5deaa        mysql               "docker-entrypoint..."   27 minutes ago      Up About a minute           3306/tcp             wordpress_dbserver_1
4188faef2128        dataserver          "sh"                     47 minutes ago      Exited (0) 20 minutes ago                        dataserver
```

http://localhost にアクセスすると起動画面が確認できます。

データ専用コンテナにボリュームがマウントされていることを確認します。

```bash:
# コンテナにアタッチ
$ docker start -ia dataserver
/ #

# ボリュームを確認
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # ls /var/
lib    spool  www
/ # ls /var/lib/
mysql
/ # ls -ltr /var/lib/mysql/
total 188448
-rw-r-----    1 999      999       50331648 Jan 21 20:48 ib_logfile1
-rw-r-----    1 999      999             56 Jan 21 20:48 auto.cnf
drwxr-x---    2 999      999           4096 Jan 21 20:48 performance_schema
drwxr-x---    2 999      999           4096 Jan 21 20:48 mysql
drwxr-x---    2 999      999          12288 Jan 21 20:49 sys
-rw-r-----    1 999      999            667 Jan 21 20:50 ib_buffer_pool
-rw-r-----    1 999      999       79691776 Jan 21 20:51 ibdata1
drwxr-x---    2 999      999           4096 Jan 21 20:51 wordpress
-rw-r-----    1 999      999       50331648 Jan 21 20:51 ib_logfile0
-rw-r-----    1 999      999       12582912 Jan 21 20:53 ibtmp1
```

##データ専用コンテナのバックアップとリストア

`docker export`コマンドでデータ専用コンテナをtarファイルに出力することでバックアップすることができます。
また、作成したtarファイルを展開してデータ専用コンテナをリストアすることができます。