docker-compose.yml個人的Tips集

Docker Compolseはとても便利ですね。私も業務内外で利用しています。
しかし、一度環境構築したあとは、docker-compose.ymlを修正する機会が少なく、ファイルに定義されている、項目やオプションの意味を忘れてしまうことが多いです。
気になった都度、調べては忘れてというサイクルを何度も繰り返しているため、今後のために1つに記事にまとめようと思います。

本記事では、私が感じた`docker-compose.yml`の個人的ポイントをいくつか記載します。

## 題材とするdocker-compose.yml

本記事は、Railsを使って個人開発しているサービスの`docker-compose.yml`を題材とします。
リポジトリは、 https://github.com/yuki0920/supplebox ですが、日々メンテしているので、本記事とファイル構成が若干変わっているかもしれません。

```
version: '3'
services:
  db:
    image: postgres
    ports:
      - '5432:5432'
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_HOST_AUTH_METHOD: trust
  web:
    build: .
    command: bundle exec rails server -p 3000 -b '0.0.0.0'
    depends_on:
      - db
    ports:
      - '3000:3000'
    environment:
      DATABASE_HOST: 'db'
    tty: true
    stdin_open: true
    volumes:
      - .:/myapp:delegated
volumes:
  pgdata:

```

## volumesについて
### volumesの`pgdata:/var/lib/postgresql/data`の`pgdata`とは何か?
```
volumes:
  - pgdata:/var/lib/postgresql/data
```
のpgdataはデータボリューム(単にボリュームともいう)を指しています。データボリュームとは、Docker Engine上に確保した領域のことを指しています。このデータのマウント方法を**ボリュームマウント**と呼びます。

Docker Engine上の領域は、下記のように確認できます。
Rails + Dockerの場合、volumesにpgdataを渡すと、`アプリケーション名_pgdata`のボリュームが作成されます。

```
$ docker volume ls
DRIVER              VOLUME NAME
local               <app_name>_pgdata
```

[Compose ファイル・リファレンス — Docker-docs-ja 17.06 ドキュメント](https://docs.docker.jp/compose/compose-file.html#id16)

### volumesの`pgdata:/var/lib/postgresql/data`の`/var/lib/postgresql/data`とは何か?

先と同じ例ですが、

```
volumes:
  - pgdata:/var/lib/postgresql/data
```
の`/var/lib/postgresql/data`はコンテナ上のデータが保管されている場所です。
postgresコンテナでは、デフォルトのデータ保管場所が`/var/lib/postgresql/data`となります。
このデータの保管場所は、コンテナごとに異なっており、mysqlコンテナならば、`/var/lib/mysql`となります。
こうしたデータの保管場所については、ドキュメントの「**Where to Store Data**」の項目に記載があります。

https://hub.docker.com/_/postgres
https://hub.docker.com/_/mysql

### volumesの`.:/myapp`の`.`とは何か?
```
volumes:
  - .:/myapp
```
の`.`はDockerホスト上のカレントディレクトリを指しています。こちらは、Docker Engine上ではなく、Dockerホスト上というのが先と異なるポイントです。
このようなボリュームのマウント方法をバインドマウントと呼びます。

### Dockerにおける2つのボリュームのマウント方法は2通り
Dockerでは、データ領域をマウントする方法が2通りあることがわかりますので、簡単にまとめます。

#### 1. ボリュームマウント

ボリュームマウントが良いケース

- Dockerほすとからへんしないとき(例えば、データベース用のコンテナなど）

[ボリュームの利用 | Docker ドキュメント](https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/)

#### 2. バインドマウント

バインドマウントがよいケース

- ディレクトリの変更をDockerコンテナに反映したいとき(例えば、アプリケーション用のコンテナなど)

[バインドマウントの利用 | Docker ドキュメント](https://matsuand.github.io/docs.docker.jp.onthefly/storage/bind-mounts/)


## stdin_openとttyについて
### `stdin_open: true`とは何か?
stdin_openとは標準入出力とエラー出力をコンテナに結びつける設定です。
`docker run -it <container_name>`の**-i**にあたる設定です。

### `tty: true`とは何か?
ttyとは、擬似端末(キーボードによる入力)をコンテナに結びつける設定です。
`docker run -it <container_name>`の**-t**にあたる設定です。

[ttyとかptsとかについて確認してみる - Qiita](https://qiita.com/toshihirock/items/22de12f99b5c40365369)

### コンテナのシェルを起動するには
`docker run`コマンドの-itオプションについて確認します。

> （シェルのような）インタラクティブなプロセスでは、コンテナのプロセスに対して tty を割り当てるために、 -i -t を一緒に使う必要があります。
[Docker run リファレンス — Docker-docs-ja 17.06 ドキュメント](https://docs.docker.jp/engine/reference/run.html#foreground)

ドキュメントどおりですが、-itはシェルを起動する際に必要なオプションです。
docker-compose.ymlのstdin_openとttyは同様の役割として、シェルを起動するためのものと理解しておくのが良さそうです。

## さいごに
今後も気になった項目、設定ががあれば追記していきます。
ご指摘等あれば、コメントいただければ幸いです。