Compose file version3のリファレンス

# この記事は今後，Zennで更新します．

https://zenn.dev/goforbroke/articles/a041488b6e548c886535

---

docker-composeで利用するversion 3の設定をまとめる．

# Docker Engineが対応するファイルフォーマットのバージョン

[Compose and Docker compatibility matrix](https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix)

`1.13.0+` 以降がCompose file verison 3.0に対応する．

# 設定

## build

指定したディレクトリにあるdockerfileでコンテナを起動する．
context, dockerfile, argsで指定もできる．

```yaml
build: ./dir

build:
  context: ./dir
  dockerfile: Dockerfile-alternate
  args:
    buildno: 1
```

## cap_add, cap_drop

コンテナの権限を制限して起動する．
[man 7 capabilities](https://linuxjm.osdn.jp/html/LDP_man-pages/man7/capabilities.7.html) の権限が指定できる．

```yaml
cap_add:
  - ALL

cap_drop:
  - NET_ADMIN
  - SYS_ADMIN
```

## command

デフォルトのコマンドを上書きして起動する．
配列形式で引数を渡しても良い．

```yaml
command: bundle exec thin -p 3000
```

```yaml
command: ["bundle", "exec", "thin", "-p", "3000"]
```

## configs

サービスのconfigを別ファイルにまとめて指定ができる．
`configs` でリソースをまとめて定義できる．

```yaml
version: "3.3"
services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    configs:
      - my_config
      - my_other_config
configs:
  my_config:
    file: ./my_config.txt
  my_other_config:
    external: true
```

## cgroup_parent

コンテナが属する container_group を指定する．
swarm　modeでは無視される．

```yaml
cgroup_parent: m-executor-abcd
```

## container_name

コンテナ名を指定する．
ユニークである必要があるため，swarm modeでは使えない．

```yaml
container_name: my-web-container
```

## credential_spec

Windows専用．

```yaml
redential_spec:
  file: c:/WINDOWS/my-credential-spec.txt

credential_spec:
  registry: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs
```

## deploy

コンテナ群のデプロイと運用条件の設定．
`docker stack deploy` を使ったswarm modeでのみ有効になる．

`docker-compose up` と `docker-compose run` では無視される．

```yaml
version: '3'
services:
  redis:
    image: redis:alpine
    deploy:
      replicas: 6
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
```

## devices

ホストのデバイスをコンテナのデバイスに割り当てる．
`docker stack deploy` を使ったswarm modeでは無視される．

```yaml
devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"
```

## depends_on

コンテナの依存関係を定義する．
次の例では， `web` は `db` と `redis` に依存する．

`docker stack deploy` を使ったswarm modeでは無視される．

```yaml
version: '3'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres
```

依存は起動の順序に関係し， `db` と `redis` が起動してから `web` が起動する．

```
dbが起動し，且つredisが起動 -> webが次に起動
```

## dns

DNSサーバを指定する．
`docker stack deploy` を使ったswarm modeでは無視される．

```yaml
dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9
```

## dns_search

DNSで検索するドメインを指定する。
`docker stack deploy` を使ったswarm modeでは無視される．

```yaml
dns_search: example.com
dns_search:
  - dc1.example.com
  - dc2.example.com
```

## tmpfs

コンテナ内でtmpfsを使用するディレクトリを指定する。
`docker stack deploy` を使ったswarm modeでは無視される．

```yaml
tmpfs: /run
tmpfs:
  - /run
  - /tmp
```

## entrypoint

コンテナが実行するファイルを設定する。
デフォルトのエントリポイントを上書きする。
`entrypoint` を指定すると、既存の `ENTRYPOINT` `CMD` は実行しない。

```yaml
entrypoint:
    - php
    - -d
    - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
    - -d
    - memory_limit=-1
    - vendor/bin/phpunit
```

## env_file

コンテナの環境変数を別ファイルにまとめて指定ができる。
既存の環境変数があれば `env_file` の値で上書きする。
`build` オプションと合わせて指定すると、build中は `enviroment` で指定した、環境変数は見えないことに注意。
`build` に変数を渡す場合は `args` オプションで指定する。

```yaml
env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env
```

`env_file` の中身は `VAR=VAL` 形式で設定する。

```ini
# Set Rails/Rack environment
RACK_ENV=development
```

## environment

コンテナの環境変数を追加する。
`env_file` の違いはdocker-comose.yamlに直接記述すること。
`build` オプションと合わせて指定すると、build中は `enviroment` で指定した、環境変数は見えないことに注意。
`build` に変数を渡す場合は `args` オプションで指定する。

```yaml
environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET
```

## expose

コンテナ内に限定して公開するポートを指定する。
exposeで公開したポートは linked servicesからのみアクセスが可能。

ホスト向けに公開したい場合は `ports` オプションを使用すること。

```yaml
expose:
 - "3000"
 - "8000"
```

## external_links

docker-composeのスコープ外にあるコンテナと通信する．

- `docker-compose.yaml` のスコープ外
- Composeのスコープ外

docker-composeで起動するコンテナ群が，他コンテナに共通サービスを提供している場合に活用できる．
`<container name>:<alias name>` で `link` のように動作する．

```yaml
external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql
```

## extra_hosts

コンテナ内にホスト名とIPアドレスの対応表を設定する．

```yaml
xtra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"
```

設定内容は `/etc/hosts` に反映する．

```
162.242.195.82  somehost
50.31.209.229   otherhost
```

## healthcheck

コンテナのサービス死活監視に利用するコマンドを設定する．


```yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3
```

imageで設定されたヘルスチェックを無効にしたい場合は `disable:true` を設定する．

```yaml
healthcheck:
  disable: true
```

## isolation

コンテナの分離技術を指定する．

- Linux: `default`
- Windows: `default`, `process`, `hyperv`

## labels

`Docker labels` を使ってコンテナにメタデータを付加する．
メタデータはDNSの逆引き形式で記述すること．

```yaml
labels:
  com.example.description: "Accounting webapp"
  com.example.department: "Finance"
  com.example.label-with-empty-value: ""

labels:
  - "com.example.description=Accounting webapp"
  - "com.example.department=Finance"
  - "com.example.label-with-empty-value"
```

## links

コンテナと他のサービスを繋げる．
リンクに属するサービスの名前を別名で定義することもできる．
`SERVICE:ALIAS`

```yaml
web:
  links:
   - db
   - db:database
   - redis
```

生成したリンクの名前は，到達可能なホスト名とみなされる．

### 注記

- `links` と `networks` を両方定義した場合，リンクを有するサービスは通信するために1つ以上のネットワークを共有する必要がある．
- `docker stack deploy` を使ったswarm modeでは無視される．

## logging

サービスのロギングを設定する．

```yaml
logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"
```

コンテナのサービスに対するロギング形式は `driver` で指定する．
`--log-driver` と同じ意味を持つ．

デフォルトはjson-file

```yaml
driver: "json-file"
driver: "syslog"
driver: "none"
```

### 注記

`json-file` と `journald`ドライバは，次のログから直接取得する．

- `docker-compose up`
- `docker-compose logs`

他のドライバはログを出力しない

### syslog

ロギングはオプションをkey-valueで指定する．

```yaml
driver: "syslog"
options:
  syslog-address: "tcp://192.168.0.42:123"
```

### json-file

```yaml
services:
  some-service:
    image: some-service
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"
```

## network_mode

ネットワークモードを指定する．
`service:[service name]` の形式と合わせて，docker client の `--network` と同じ意味を持たせる．

```yaml
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
```

### 注記

- `docker stack deploy` を使ったswarm modeでは無視される．
- `network_mode: "host"` は `links` と組み合わせられない．

## networks

`networks` を最上位として，使用するネットワークを列挙する．

```yaml
services:
  some-service:
    networks:
     - some-network
     - other-network
```

## ALIASES

ネットワーク上のサービスを `Aliases` (ホスト名の代替)で定義する．
同じネットワーク情報他のコンテナは，サービス名もしくはエイリアスで接続できる．

```yaml
services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
         - alias3
      other-network:
        aliases:
         - alias2
```

3つのサービス( `web, worker, db` )が，2つのネットワーク( `new, legacy` )を介する例．
dbサービスはnewネットワークからホスト名db，またはdatabaseで接続できる．
legacyネットワークからはdbまたは `mysql` で接続できる．

```yaml
version: '2'

services:
  web:
    build: ./web
    networks:
      - new

  worker:
    build: ./worker
    networks:
      - legacy

  db:
    image: mysql
    networks:
      new:
        aliases:
          - database
      legacy:
        aliases:
          - mysql

networks:
  new:
  legacy:
```

### 注記

ネットワーク全体のエイリアスは複数のコンテナが例え複数のサービスであっても共有できる．
そうならば，コンテナ名を解決することは保証できない．

## IPV4_ADDRESS, IPV6_ADDRESS

固定のIPv4アドレス，IPv6アドレスを指定する．

`networks` セクションの最上位に対応するネットワーク構成には，
静的アドレスをカバーするサブネット構成を持つ `ipam` ブロックが必要．

```yaml
version: '2.1'

services:
  app:
    image: busybox
    command: ifconfig
    networks:
      app_net:
        ipv4_address: 172.16.238.10
        ipv6_address: 2001:3984:3989::10

networks:
  app_net:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
      -
        subnet: 172.16.238.0/24
      -
        subnet: 2001:3984:3989::/64
```

## pid

```yaml
pid: "host"
```

PIDモードをホストPIDモードに設定する．
これはコンテナとホストのオペレーティングシステムとのPIDアドレス空間の共有を有効にする．

このフラグで起動されたコンテナはベアメタルマシン上の他コンテナにアクセスと操作ができる．
他コンテナから逆のことも可能．

## ports

ポートを公開する．

### 注記

`HOST:CONTAINER` 形式で 60より小さいポートを指定すると，エラーとなる．
YAMLが　`xx:yy` の形式を60進数と解釈するため．
回避するにはポート番号を明示的に文字列で指定する．

### SHORT SYNTAX

`HOST:CONTAINER` でホストとコンテナのポートを併記する．
HOSTが指定されなければ，ランダムなポートが割り振られる．

```yaml
ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"
 - "6060:6060/udp"
```

### LONG SYNTAX

short syntaxで表現しきれない追加設定を許可する．

- `target` : コンテナ内のポート
- `published` : 公開されているポート
- `protocol` : 公開するポートのプロトコル(TCP/UDP)
- `mode` :
    - `host` : 各ノードにホストのポートを公開する
    - `ingress` : swarm modeの入力でロードバランスされるポート

```yaml
ports:
  - target: 80
    published: 8080
    protocol: tcp
    mode: host
```

#### 注記

long syntaxは3．2以降から利用可能．

## secrets

サービスごとの `secrets` 設定を用いて，機密へのアクセス権限を許可する．

### 注記

機密は最上位に既に存在しているか，定義しなければならない．

### SHORT SYNTAX

short syntax形式の変数はsecret nameだけ指定できる．
これによりコンテナの機密にアクセスできる．
そして，コンテナ内に `/run/secrets/<secret_name>` としてマウントする．

指定元の名前とマウントポイントはどちらもsecret nameとなる．

#### Docker 1．13．1での制限

Docker 1.13.1のバグにより，短い構文を使用するとアクセス権000のsecretがマウントされる．
コマンドがルートユーザとして実行されない場合， short syntaxで定義されたsecretがコンテナ内で読み取れないことを意味する．

Docker 1.13.1でこの問題を回避するには short syntaxを使うこと．

### LONG SYNTAX

long syntaxはサービスのタスクコンテナ内で，secretがどのように生成するかを詳細に与える．

- `source` : dockerに存在するconfigの名前
- `target` : サービスのタスクコンテナにマウントされるパス付きのファイル名．デフォルトは `/<source>` 
- `uid` , `gid` : サービスのタスクコンテナ内でマウントしたconfigのUIDまたはGIDを数字で表現する．デフォルトは `0` ．Windowsではサポートしない．
- `mode` : サービスタスクのコンテナ内でマウントするファイルのパーミッション．8進数で表現し，Linuxの権限設定に準ずる．デフォルトは `0444`．
    - Configは一時的なファイルシステムにマウントされるため，書き込みビットを立てても無視される．実行ビットはセットできる．

次の例は `my_config` を コンテナ内で `redis_config` として指定する例．

```yaml
version: "3.3"
services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    configs:
      - source: my_config
        target: /redis_config
        uid: '103'
        gid: '103'
        mode: 0440
configs:
  my_config:
    file: ./my_config.txt
  my_other_config:
    external: true
```

short syntaxとlong syntaxは混在することが可能．


## cgroup_parent

コンテナへオプションの親cgroupを指定する．

```yaml
cgroup_parent: m-executor-abcd
```

### 注記

version 3のswarm modeでは無視される．

## container_name

コンテナ名を指定する。指定がない場合はデフォルト名が生成される。
次の例では `my-web-container` というコンテナ名になる。

```yaml
container_name: my-web-container
```

コンテナ名を指定すると1コンテナしか起動できない。
これはコンテナ名は一意を保つ必要があるため。
複数起動をするとエラーになる。

### 注記

version 3のswarm modeでは無視される．

## credential_spec

管理サービスアカウントの資格情報の設定。(Windowsのみ)
`credential_spec` は `file://<filename>` または `registry://<value-name>` で記述する必要がある．

`file` を使う時，Dockerのデータディレクトリに `CredentialSpecs` ディレクトリを作って参照するファイルを置く．
データディレクトリのデフォルトは `C:\ProgramData\Docker\` になる．

次の例は `C:\ProgramData\Docker\CredentialSpecs\my-credential-spec.json` に証明書を置いた例．


```yaml
credential_spec:
  file: my-credential-spec.json
```

`regisitry:` を使うと，デーモンのホストのWindowsレジストリから証明書を読む．

```yaml
credential_spec:
  registry: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs
```

### 注記

このオプションはv3.3で追加


## deploy

デプロイと動作中のサービスに関連する設定を指定する．
このオプションは docker stack deploy の swarm に作用し， `docker-compose up` と `docker-compose run` に無視される．

```yaml
version: '3'
services:
  redis:
    image: redis:alpine
    deploy:
      replicas: 6
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
```

### 注記

version 3限定

### ENDPOINT_MODE

swarmに繋がっている外部クライアントに向けてサービスディスカバリ方法を指定する．

- `endpoint_mode: vip`

デフォルト値．DockerのサービスをVirtual IPに割り当てる．

- endpoint_mode: dnsrr 

DNSラウンドロビンを使う．


```yaml
version: "3.3"

services:
  wordpress:
    image: wordpress
    ports:
      - 8080:80
    networks:
      - overlay
    deploy:
      mode: replicated
      replicas: 2
      endpoint_mode: vip

  mysql:
    image: mysql
    volumes:
       - db-data:/var/lib/mysql/data
    networks:
       - overlay
    deploy:
      mode: replicated
      replicas: 2
      endpoint_mode: dnsrr

volumes:
  db-data:

networks:
  overlay:
```

`endpoint_mode` のオプションはswarmモードのCLIコマンド `docker service create` でも動作する．
サービスディスカバリとネットワークの設定を更に学びたい場合は， [Configure service discovery](https://docs.docker.com/engine/swarm/networking/#configure-service-discovery) を参照すること．

#### 注記

version 3.3限定

## LABELS

サービスのラベルを指定する．これらのラベルはサービスの集合に対してのみ指定する．
サービスのコンテナに指定するものではない．

```yaml
version: "3"
services:
  web:
    image: web
    deploy:
      labels:
        com.example.description: "This label will appear on the web service"
```

コンテナへのラベルの代わりに， `deploy` の外側で`label` を使用する．

```yaml
version: "3"
services:
  web:
    image: web
    labels:
      com.example.description: "This label will appear on all containers for the web service"
```


# 参考

[Compose file version 3 reference](https://docs.docker.com/compose/compose-file/)
[Compose ファイル・リファレンス](http://docs.docker.jp/compose/compose-file.html)
[docker-compose.ymlの命令を理解して、よりDockerを有効活用したい！](http://aspec7.hateblo.jp/entry/2015/11/08/134228)
[Docker Compose - docker-compose.yml リファレンス](http://qiita.com/zembutsu/items/9e9d80e05e36e882caaa)
[コンテナの連結と操作 - Docker User Guide](http://qiita.com/zembutsu/items/f361cad9be500950939f)