初めてのdocker-compose

この記事では初めての人向けにdocker-composeの使い方を説明します。
Docker自体の概念やDockerfileの書き方については[Dockerの基本的な使い方](https://qiita.com/kitanotamayura/items/b240eb850514f3ad2381)を参考にしていただけると嬉しいです。
docker-composeを使ってDockerをより便利に使えるようになることを目標にします。


#目次
[1.概要](#1-概要)
[2.docker-composeを使うメリット](#2-内容い)
[3.docker-compose.ymlの書き方](#3-内容ろ)
[4.docker-composeコマンド](#4-内容は)
[5.おわりに](#5-おわりに)

## 環境

- MacBook Air (Retina, 13-inch, 2020)
- Docker version 20.10.7
- docker-compose version 1.29.2


#1. 概要

docker-composeは複数のdockerイメージやdockerコンテナを自動的に扱ったり、Dockerコマンドで設定することをまとめて実行させる機能になります。
このときに、設定を書くファイルをdocker-compose.ymlと言います。


#2. docker-composeを使うメリット

概要でも書きましたが、docker-composeを使う主なメリットは

- dockerコマンドの自動化
- 複数のdockerイメージやdockerコンテナを扱いやすくする

になります。docker-compose.ymlに自動化の設定ファイルを書くことで基本的には一つのコマンドですべてを一度に実行できるようになります。また、複数のDockerイメージに対して書くことによって同時に複数のコンテナを扱うことができます。


#3. docker-compose.ymlの書き方

ここでは、　docker-composeの設計図に当たるdocker-compose.ymlの書き方について簡単に説明します。
具体的にはDockerfileからdockerイメージをbuildする場合とdockerイメージをpullしてくる場合それぞれ分けてjupyter labをコンテナ内で作る場合を例として解説します。

## Dockerfileを使う場合

下のサンプルコードを例として説明します。

1. 初めにdocker-composeのバージョンを`version:` の次に書きます。今回はバージョン`"3"`になります。
2. 次に使うイメージを`service:`の次に行にインデントを開けてサービスとして`echo:`を設定します。ここのサービス名は自由に名前をつけて大丈夫です。
3. この次の行からインデントを開けてコマンドを設定していきます。
    1. `build:`  ;ここはdockerコマンド`docker build`以下に対応します。Dockerfileの名前を"Dockerfile"としたときにはDockerfileがあるPathを、他の名前をつけた場合にはPathとファイル名を書きます。
    2. `ports:`  ;ここにはdocker run -pに対応する情報を書きます。`外部のport番号:コンテナ内のポート番号`の順番で設定します。
    3. `volumes:`  ;ここにはdocker run -vに対応する情報を書きます。これはコンテナの外部の./code以下のコードがコンテナの内部の/code以下と対応させています。


```docker-compose.yml
version: "3"
services:
  echo:
    build: .
    ports:
      - 8889:8888
    volumes:
      - ./code:/code
```


## docker hubを使う場合

こちらも基本的には上記の場合と大体同じになります。違う点だけ説明していきます。

1. `image:`  ;ここには`docker pull` 以下に対応します。このサンプルでは`https://hub.docker.com/r/jupyter/datascience-notebook`からdockerイメージをpullしています。
1. `environment:`    ;ここにはコンテナ内の環境変数を設定します。
1. `command:`  ;ここにはdocker runをしたときに最後に実行されるコマンドを書きます。


```docker-compose.yml

version: "3"
services:
  notebook:
    # https://hub.docker.com/r/jupyter/datascience-notebookからimageをpullする
    image: jupyter/datascience-notebook
    # ポートの設定("ホスト：コンテナ")
    ports:
      - "9999:8888"
    # 環境変数の設定
    environment:
      - JUPYTER_ENABLE_LAB=yes
    # ボリューム(データの永続化の場所)の設定(ホスト:コンテナ)
    # ホスト内のworkディレクトリとコンテナ内の/home/jovyan/workディレクトリが紐づいているイメージ
    volumes:
      - ./work:/home/jovyan/work
    # 最後にjupyterLabに接続するためのコマンドを実行する。
    command: start-notebook.sh --NotebookApp.token=''
```

#4. docker-composeコマンド

### `docker-compose up`

docker-composeがあるディレクトリでdockerイメージの作成・取得から`docker run`までをまとめて実行します。

オプション
- `-b` ：バックグラウンド実行
- `--build` ：コンテナを開始前にイメージを構築する

```terminal
$ docker-compose up
```

### `docker-compose down`

サービスを停止、削除をします。

```terminal
$ docker-compose down
```

### `docker-compose ps`

実行中のコンテナの一覧を表示します。

```terminal
$ docker-compose down
```

### `docker-compose log`

実行中のコンテナのログを表示します。

```terminal
$ docker-compose log
```

#5. おわりに

簡単にdocker-composeの使い方を説明をしてみました。
ここで紹介した以外のコマンドやdocker-compose.ymlの文法については[Document](https://docs.docker.jp/compose/toc.html)を参考にしてください。

dockerの細かいコマンドをすべてdocker-compose upに置き換えることができるので大変便利な機能になります。
ぜひ、みなさん使ってみてください！