JAWS DAYS 2017 ワークショップ Docker on Elastic Beanstalk 〜Days after tomorrow〜 (1)

この記事では、複数のDockerコンテナで構成される環境を構築するための設定例を具体的に解説します。ワークショップのフォローアップではありますが、一般的な事柄を扱いますので、ワークショップに参加されていない方にもお読み頂ける内容です。

# ワークショップ
こんにちは。Emotion Techの子安です。3月もそろそろ終わりだというのに、まだ寒い日が続きますね。陽だまりの恋しい今日このごろです。

さて、先日開催されたJAWS DAYS 2017にて、ワークショップ「Docker on Elastic Beanstalk 〜明日から本番で使えるかも〜」を担当いたしました。多数のお申込みとご参加ありがとうございました。

- [イベントページ](http://jawsdays2017.jaws-ug.jp/session/1797/)
- [スライド](https://www.slideshare.net/akirakoyasu/workshop-docker-on-elastic-beanstalk)

当日の様子はこんな感じでした。

![P3111037.JPG](https://qiita-image-store.s3.amazonaws.com/0/169518/b0740e26-70ff-17f8-8eba-bdc5f655b6af.jpeg)

![P3110990.JPG](https://qiita-image-store.s3.amazonaws.com/0/169518/cc9b534e-99a0-23fd-2c5f-739dd73e0373.jpeg)

ハンズオンがメインということで、環境を構築して動かすことにフォーカスした内容だったのですが、終了後に記入して頂いたアンケートの中で、コンテナの設定や、ファイルの内容についてよく知りたいというご要望を頂きました。そこで、今回はワークショップで触れられなかった、そのあたりのことを解説したいと思います。（Dockerそのものについての解説は行いません） 長くなりそうなので、2,3回に分けて掲載する予定です。

# リポジトリとコンテナの構成
リポジトリはこちらです。ハンズオンの手順書やコンテナの設定などが入っています。
https://github.com/akirakoyasu/elastic-beanstalk-workshop

## コンテナの構成
![workshop (1).png](https://qiita-image-store.s3.amazonaws.com/0/169518/98f086db-1746-7637-d3d1-f0e14f380577.png)

静的コンテンツ配信かつRailsへのプロキシとなるwebコンテナがあり、Railsが動いているappコンテナがあり、更にdbコンテナがあるという構成です。

# コンテナ定義ファイル
まずはコンテナを定義するファイルから具体的に見ていきます。 [docker-compose.yml](https://github.com/akirakoyasu/elastic-beanstalk-workshop/blob/master/docker-compose.yml) を参照ください。docker-compose.ymlは、大きく `services` `volumes` `networks` の3つのセクションに分けられます。

※ 実はElastic Beanstalkはdocker-compose.ymlファイルを参照しませんので、同様の内容をDockerrun.aws.jsonに記述しています。Dockerrun.aws.json固有の設定は次回以降に解説します。

## services
コンテナをサービスとして定義するセクションです。ここで、 `web` `app` `db` コンテナをそれぞれ定義しています。

## volumes
ホストからコンテナへマウントするディスク領域（ボリューム）を定義するセクションです。ここで、DBのデータ領域となるボリューム `eb.workshop.db` を名前付きボリュームとして定義しています。イメージがボリュームを要求する場合、定義しなくても自動的にボリュームが作成されますが、名前を付けて定義しておいたほうが後で扱いやすいので明示的に定義するようにしています。

## networks
コンテナが接続するネットワークを定義するセクションです。ここで、ネットワーク `eb.workshop` を定義しています。docker-composeを使用した場合、定義しなくてもデフォルトで1つネットワークが作成されますが、定義しておいたほうが後で扱いやすいので明示的に定義するようにしています。

# 各コンテナの設定

以降では、順にそれぞれのコンテナで利用している設定を見ていきましょう。

## webコンテナ
まずは一番単純なwebコンテナから行きます。

```docker-compose.yml
  web:
    image: nginx:1.10.3
    environment:
      APPLICATION_ENV: development
      APPLICATION_ROLE: web
    labels:
      eb.workshop.role: web
    ports:
      - "80:80"
    networks:
      - eb.workshop
    depends_on:
      - app
    volumes:
      - ./web/conf.d:/etc/nginx/conf.d:ro
      - ./web/html:/var/www/html:ro
```

- `image`: 公式のnginxイメージを指定しています。予期していない変更を予防するため、バージョンタグを必ず指定しましょう。
- `environment`: 環境変数を指定します。コンテナの役割やDEV/PROD環境の区別などを持たせておくとよいでしょう。
- `labels`: コンテナにつけるラベルを指定します。必須ではありませんが、付けておくとCLIでのフィルタリングなどがしやすくなります。
- `ports`: ホスト側の80番ポートとコンテナ側の80番ポートをマッピングしています。
- `networks`: コンテナが接続するネットワーク（networksのセクションで定義したもの）を指定します。
- `depends_on`: このコンテナが依存するコンテナを指定します。webコンテナはappコンテナへプロキシしますので、appコンテナを指定しています。
- `volumes`: コンテナにマウントするボリュームを指定します。ボリュームのマウントにはいくつか種類がありますが、ここではホスト側のディレクトリをdocker-compose.ymlファイルからの相対パスで指定して、nginxの設定ファイルと、配信する静的コンテンツをコンテナ側で読み込めるようにしています。

## dbコンテナ
次はdbコンテナです。使用しているMySQLイメージの挙動による設定がいくつかあります。（webコンテナと重複する項目は割愛します）

```docker-compose.yml
  db:
    image: mysql:5.7.17
    environment:
      APPLICATION_ENV: development
      APPLICATION_ROLE: db
      MYSQL_ROOT_PASSWORD: password
    labels:
      eb.workshop.role: db
    networks:
      - eb.workshop
    volumes:
      - ./db/config/db.cnf:/etc/mysql/conf.d/db.cnf
      - ./db/script/db-init.sql:/docker-entrypoint-initdb.d/db-init.sql
      - eb.workshop.db:/var/lib/mysql
```

- `image`: 公式のmysqlイメージを指定しています。
- `environment`: MySQLのrootユーザのパスワードを環境変数 `MYSQL_ROOT_PASSWORD` で指定する必要があります。
- `volumes`: ここでは3つのマウントを指定しています。1つめはMySQLの設定ファイル、2つめは初期化時に実行されるSQLスクリプトファイル、3つめはデータ領域となるディレクトリです。

MySQLイメージの挙動により、 `MYSQL_ROOT_PASSWORD` 環境変数がrootパスワードとして使用され、初期化時に `/docker-entrypoint-initdb.d/db-init.sql` のSQLが実行されます。このあたりの挙動については、 [Docker Hubのページ](https://hub.docker.com/_/mysql/) に記載されています。

# 次回へ
次はappコンテナですが、少し長くなりそうなので、つづきは次回にしたいと思います。

次回の記事： [JAWS DAYS 2017 ワークショップ Docker on Elastic Beanstalk 〜Days after tomorrow〜 (2)](http://qiita.com/wizpra-koyasu/items/9603273b3e99107a7ad8)