Docker for Windowsでチーム開発するためにやったこと

この記事は[Docker2 Advent Calendar 2016](http://qiita.com/advent-calendar/2016/docker2)の13日目の記事です。

# はじめに

## モチベーション

普段はアプリケーションエンジニアとして働いているtak-solderです。
来年から新しいアプリケーションの開発に着手するのですが、その開発環境にDocker(Docker for Windows)を使いたいなと思っていて、現在導入に向けて奮闘中です。

## なぜDocker(Docker for Windows)なのか？

* Windowsで開発している
    ⇒ 今のところMacで開発するという選択肢はない
* ローカルに仮想環境を立てて開発したい
    ⇒ でも、Vagrant(VirtualBox)の共有フォルダは遅いんだよなー
* 新しいシステムはマイクロサービスを組み合わせて構築したい
    ⇒ Vagrantだと、複数の仮想マシンを立てるのは厳しいなー
* 最近、Dockerというものが流行っている
    ⇒ 複数コンテナ立てられて、マイクロサービス向きらしい
* Docker for Windowsの正式版がリリースされた
    ⇒ VirtualBox使わなくても、共有フォルダが使えるっぽい

一言でいうと、**流行っている環境を使って、流行っているシステム構成の開発がしたい**ということです。

# これまでにやったこと

## Dockerの勉強

まずは、ググったり、Qiitaとかはてブで調べて、Dockerの基本操作をしていました。
Dockerを起動する方法や、コンテナを作るにはDockerfileを書いて``docker build``するとか、DockerComposeを使えば、複数のコンテナを一度に起動/停止できるという粒度の情報であれば、Webの情報だけで十分だと思います。

実際に``Dockerfile``や``docker-compose.yml``を書くのであれば、Webの情報だけだと効率が悪かったので、[オライリー本](https://www.oreilly.co.jp/books/9784873117768/)を買って読んでいます。
まだ、全部読み終えた訳ではありませんが、開発環境の作成程度であれば、前半を読むだけでもかなり理解が深まると思います。

## コンテナの作成

開発に必要なLAMP環境を作るために、Dockerfileを書いて、コンテナを作っていきます。
VagrantではAnsibleでプロビジョニングをしていたので、Dockerfileにコマンドを書いていくのは大変かなとも思ったのですが、MySQLやRedisは公式のコンテナを使えるので、思ったほどではありませんでした。

実際に本番でもコンテナを使うとなったら、インフラエンジニアを口説いてしっかりしたものを作ってもらった方がいいと思います。

## オレオレベストプラクティス

実際に開発を行う中には、フロントエンジニアなど、そもそもDockerって何という人がいるので、
開発環境の構築は知識がなくても、使える必要があります。

そこで、暫定のオレオレベストプラクティスを考えました。
前提として、最低限コマンドプロンプトを触れるくらいの知識は必要です。

### コンテナの共有

コンテナの共有方法は、試験段階では作成したコンテナを``docker save``でファイルに書き出して、共有するようにしました。

コンテナファイルをコピーして、``docker load -i [ファイル名]``のコマンドを叩くだけなので、簡単なマニュアルで導入できました。

### コンテナの起動

コンテナの起動も``docker-compose up``のコマンドを叩くだけですぐに開発ができる状態にするのが、一番簡単だと思います。

やり方をいくつか考えたのですが、プログラムなどと一緒に``docker-compose.yml``もGitにコミットして、プロジェクトのルートディレクトリでコマンドを叩くようにしてもらいます。

### データの永続化

Dockerを知らない人が苦戦するのは、データの永続化(特にDB周り)かなと思います。

データコンテナの話をしても、Dockerを理解していない人には訳が分からないとおもうので、
開発途中に発生した永続化したいデータはプロジェクト内のディレクトリに保存されるようにします。

ディレクトリ内に``.gitignore``だけをコミットしておき、データはコミットされないようにします。(もし、最初に定型のデータが必要になれば、そのときだけ一時的にコミットすればいいと思います。)

最終的な``docker-compose.yml``のサンプルを下記です。

```YAML
version: '2'

services:
  web:
    image: image:tag
    ports:
      - "80:80"
    volumes:
      - .:/path/to/project/root
    links:
      - mysql
      - redis

  mysql:
    image: mysql:5.6
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: PASSWORD
      MYSQL_DATABASE: DATABASE
      MYSQL_USER: USER
      MYSQL_PASSWORD: PASSWORD
    volumes:
      - ./docker-data/mysql:/var/lib/mysql

  redis:
    image: redis:3
    volumes:
      - ./docker-data/redis:/data
```

# これからやっていきたいこと

上記のようなことをして、チーム内のエンジニアが無事にDockerを使って開発環境を整えることができました。

最後に、本格導入に向けてのToDoリストを書いて終わりにしたいと思います。

## Dockerリポジトリを利用する

まだ、作成したコンテナイメージが1つだけなので、コンテナファイルの共有で済みますが、実際に開発するとなると、多くのコンテナを管理する必要が出てきて、自然とリポジトリサービスを使うことになると思います。

今のところ、有力だと思っているのがAWSの[Amazon EC2 Container Registry](https://aws.amazon.com/jp/ecr/)です(国内のサーバを使えるし、他でもAWSにはお世話になっているので･･･)

## Jenkinsのコンテナを作成する

せっかく、Dockerを使うのであれば、CIもコンテナで完結できた方が便利だと思います。
Jenkinsのコンテナを作れば、ローカルでビルドまでできるので、気軽にビルドできるようになるのではないでしょうか。

## 本番環境への適用

インフラエンジニアを口説いて、便利だと思ってもらえれば、開発だけでなく本番でも使っていけたらいいですね。

# まとめ

まだ、試用段階なので「Dockerオススメです！」とは書けませんが、
今のところ順調に進められているのでオススメできるようになったら、また記事を書きます。