docker-composeをいいかげんに覚える

さすがに Docker がないと開発がめんどくさくなってきたので自分用のメモを残す。
深く理解するより、ひとまず自分が最速、最小コストで開発にこぎつけられるレベルの知識をつける。

ひとまず Mac 上で起動しながら開発してた Redis と MongoDB, Elasticsearch を Docker 化することを目的とする。

# 自分の知識レベル

Dokerfile とかいうのを書くと勝手にOSイメージをとってきて小さな仮想環境を立ててくれる。
複数の Dokerfile を書かなきゃいけないと shell script　とか書いてしんどくなるイメージ。
docker-compose を使うと docker のコマンドをあまり覚えなくても使えるらしい。

# docker-compose

Docker の image が複数ある時に取りまとめてとってきたり一度に起動したりできるもの。

例えば Redis を立ち上げたい時は下のように docker-compose.yml を書く。

```docker-compose.yml
version: "3.3"
services:
  redis:
    image: redis:4
    ports:
      - 6379:6379
```

services の下に自分が起動したい Docker image たちを羅列していく。
`image` は [Docker hub](https://hub.docker.com/) にあがっているものからとってこれる。
例えば Redis とかはここ。
https://hub.docker.com/_/redis/

大体タグ名にバージョンがついてる。
`image: {image名}:{タグ名}`

`ports` は Docker 内で起動してるポートをローカルPCのポートにフォワーディングする時に使う。
こうするとローカルPCの redis-cli で Docker の Redis につなげるようになる。

`up` コマンドで docker-compose.yml に書いてある Docker image をとってきて起動してくれる。
`-d` オプションをつけるとデーモン化してくれるが、よく起動したのを忘れ放置して電池消費がとんでもないことになったりするのでつけないで使っていく心づもり。

```bash
$ docker-compose up
```

# データを永続化する

MongoDB などデータの永続化が必要なものは valume をバインドしないと揮発してしまうらしい。

```docker-compose.yml
version: "3.3"
volumes:
  mongodb-volume:
    driver: 'local'
services:
  mongodb:
    image: mongo:3.6
    volumes:
      - mongodb-volume:/data/db
    ports:
      - 27017:27017
    command: mongod --replSet myDevReplSet
  redis:
    image: redis:4
    ports:
      - 6379:6379
```

トップレベルの `volumes` で volume の名前をつける。 driver はインストールしたらいろいろ選べるみたいだけど、とりあえず local 以外は今の所使わないのでこれ。
volumes で宣言すると Docker がいい感じにディレクトリ管理してくれるっぽい。

servces -> mongodb -> volumes でトップレベルの `volumes` で宣言した名前と Docker内のディレクトリを紐付ける。

command が プロセスの起動コマンド

# Dockerfile で分割する

Elasticsearch は plugin とか入れたいので最小限の Dockerfile を書いてディレクトリを分けて管理する。

```
$ tree
├── elasticsearch/
│    ├── config/
│    │    ├── elasticsearch.yml
│    │    └── log4j2.properties
│    └── Dockerfile
└── docker-compose.yml
```

FROM でイメージを指定、RUN で plugin をインストールする Elasticsearch の Dockerfile

elasticsearch/Dockerfile

```
FROM elasticsearch:5

RUN elasticsearch-plugin install analysis-kuromoji
```

MongoDB と同様にトップレベルの volumes に Elasticsearch 用の volumeを設定。

`build` で Dockerfile が置かれているディレクトリを指定すると Dockerfile に従って起動してくれる。

MongoDB と同様に Elasticsearch の data を置く場所をバインディング。
ローカルの config ファイルも同じように volumes でバインディング。
これでDockerfileに設定配置用の RUN を書かなくて OK。

```docker-compose.yml
version: "3.3"
volumes:
  mongodb-volume:
    driver: 'local'
  elasticsearch-volume:
    driver: 'local'
services:
  mongodb:
    image: mongo:3.6
    volumes:
      - mongodb-volume:/data/db
    ports:
      - 27017:27017
    command: mongod --replSet myDevReplSet
  redis:
    image: redis:4
    ports:
      - 6379:6379
  elasticsearch:
    build: elasticsearch
    volumes:
      - elasticsearch-volume:/usr/share/elasticsearch/data
      - ./elasticsearch/config:/usr/share/elasticsearch/config
    ports:
      - 9200:9200
```

# 最低限使う docker-compose のコマンド

## up

起動

```bash
$ docker-compose up
```

## ps
プロセスの確認。

時々終了に失敗して State が Up のままになってたりする。
State が Exit になっていれば終了している。

```
$ docker-compose ps
          Name                         Command               State                Ports
-----------------------------------------------------------------------------------------------------
elasticsearch_1              /docker-entrypoint.sh elas ...   Up      0.0.0.0:9200->9200/tcp, 9300/tcp
mongodb_1                    docker-entrypoint.sh mongo ...   Up      0.0.0.0:27017->27017/tcp
redis_1                      docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp
```

## stop

全部止める。
ps して確認したら動いてた時に止める。

## down

docker-compose 書いて試してる時に間違ってて全部やり直したい時。

`--rmi all` をすると image 取ってくるのもクリアできる。

```
$ docker-compose　down
```