ようへいの日々精進XP

よかろうもん

【俺の一行チップス】docker-compose の Extension fields を使って DRY な YAML にする(docker-compose 3.4 以降, docker-compose 2.1 以降編)

やりたいこと

docker-compose.yml を書いていて, 同じ内容を何度も何度も書いていて, 令和の時代にこれはアカンということで Anchor, Alias で少しでも DRY にしたい. DRY とは, アサヒスーパードライではなく, Don't Repeat Yourself のことなので酔っ払わないように.

諸注意

動作確認環境は以下の通り.

$  docker-compose version
docker-compose version 1.24.1, build 4667896b
docker-py version: 3.7.3
CPython version: 3.6.8
OpenSSL version: OpenSSL 1.1.0j  20 Nov 2018

やったこと

これまでの docker-compose.yml

version: '3.4'

services:
  postgresql_server:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        DB_PASSWORD: "posgre"
    container_name: postgresql
    ports:
      - "5432:5432"
    networks:
      my_net:
        ipv4_address: 10.0.101.10

  psql:
    image: postgres:9
    container_name: psql
    networks:
      my_net:
    environment:
      PGAPPNAME: pgbench
      PGHOST: 10.0.101.10
      PGUSER: pgadmin
      PGPASSWORD: posgre
      PGDATABASE: pgbench

  pgbench-prepare:
    image: postgres:9
    container_name: pgbench-prepare
    networks:
      my_net:
    environment:
      PGAPPNAME: pgbench
      PGHOST: 10.0.101.10
      PGUSER: pgadmin
      PGPASSWORD: posgre
      PGDATABASE: pgbench
    command: bash -c "dropdb pgbench ; createdb --owner=pgadmin pgbench && pgbench --initialize --scale=5"
()

environment の値が 2 箇所, 省略している部分を含めると 4 箇所に同じ内容が書かれているのでなんだか長くてダサい. けど, 一応, 構文的には問題ない.

$ docker-compose --file docker-compose.before.yml config --quiet; echo $status
0

ちなみに, docker-compose config という docker-compose.yml の内容をチェックしているコマンドがあったのは知らなかった.

令和の docker-compose.yml

以下のように, docker-compose 3.4 から (docker-compose 2.1 以降も) サポートされている, Extension fields を利用することで, docker-compose.yml のトップレベルである services と同じルートレベルに特殊フィールド (キーの頭に x- を付ける) として書くことが出来る. 尚, docker-compose 3.4 以前も Anchor と Alias を使うことが出来たが, services 内に Anchor を書く必要があった.

# ドキュメントより引用
version: '3.4'
x-logging:
  &default-logging
  options:
    max-size: '12m'
    max-file: '5'
  driver: json-file

services:
  web:
    image: myapp/web:latest
    logging: *default-logging
  db:
    image: mysql:latest
    logging: *default-logging

とのことなので, 先程の docker-compose.yml を書き直してみると以下のような感じ.

version: '3.4'

x-common_environment: &common_environment
  PGAPPNAME: pgbench
  PGHOST: 10.0.101.10
  PGUSER: pgadmin
  PGPASSWORD: posgre
  PGDATABASE: pgbench
x-networks: &common_networks
  networks:
    my_net:

services:
  postgresql_server:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        DB_PASSWORD: "posgre"
    container_name: postgresql
    ports:
      - "5432:5432"
    networks:
      my_net:
        ipv4_address: 10.0.101.10

  psql:
    image: postgres:9
    container_name: psql
    environment: *common_environment
    <<: *common_networks

  pgbench-prepare:
    image: postgres:9
    container_name: pgbench-prepare
    environment: *common_environment
    command: bash -c "dropdb pgbench ; createdb --owner=pgadmin pgbench && pgbench --initialize --scale=5"
    <<: *common_networks
 (略)

こんな感じになった. Anchor, Alias を使えば, 当然, 同じ記述を繰り返し書かなくてすむし, Extension fields でよりスッキリした感じ.

$ docker-compose --file docker-compose.yml config --quiet; echo $status
0

構文チェックも OK.

以上

メモでした.

参考

docs.docker.com

circleci.com

(完)