YAML anchors เป็นหนึ่งในความสามารถของไฟล์นามสกุล .yaml ที่ทำงานเหมือนกับการเขียน functions เราสามารถจะสร้างชุดคำสั่งบางอย่างแล้วนำไปใช้งานซ้ำๆ ได้ภายในไฟล์ .yaml หรือภายใน services แต่ละตัวของ Docker compose ได้

ลองมาดูตัวอย่างการใช้งานกันในกรณีเราจะสร้าง service ชื่อ web และ worker โดยไม่ได้ใช้ YAML anchors

version: "3.4"

services:
  web:
    build:
      context: "."
      args:
        - "APP_ENV=${APP_ENV:-prod}"
    depends_on:
      - "postgres"
      - "redis"
    env_file:
      - ".env"
    image: "nickjj/myapp"
    ports:
      - "8000:8000"
    restart: "unless-stopped"
    stop_grace_period: "3s"
    volumes:
      - ".:/app"

  worker:
    build:
      context: "."
      args:
        - "APP_ENV=${APP_ENV:-prod}"
    depends_on:
      - "postgres"
      - "redis"
    env_file:
      - ".env"
    image: "nickjj/myapp"
    restart: "unless-stopped"
    stop_grace_period: "3s"
    volumes:
      - ".:/app"

จะสังเกตุเห็นว่ามีค่าที่ซ้ำกันอยู่เช่น build, image หรือ port มากมาย

ลองใช้งาน YAML anchors กับ X properties

version: "3.4"

x-app: &default-app
  build:
    context: "."
    args:
      - "APP_ENV=${APP_ENV:-prod}"
  depends_on:
    - "postgres"
    - "redis"
  env_file:
    - ".env"
  image: "nickjj/myapp"
  restart: "unless-stopped"
  stop_grace_period: "3s"
  volumes:
    - ".:/app"

services:
  web:
    <<: *default-app 
    ports:
      - "8000:8000"

  worker:
    <<: *default-app

โค็ดสั่นลงเยอะ และเราสามารถเปลี่ยนค่าต่างๆ ได้ง่ายขึ้น มาดูวิธีใช้งานกัน

ในส่วนของ x- จะเป็นการบอกว่าโค็ดด้านล่างนี้จะสามารถนำไปใช้งานแบบ YAML anchors ได้เพื่อนำไป re-use ใช้งานใน service ต่างๆ ภายใน docker-compose และการสร้าง x- นั้นเราจำเป็นต้องวางก่อน services: และ &default-app เป็นชื่อที่เราตั้งไว้ เพื่อนำไปใช้งาน

x- เราจะเรียกกันว่า “Extension fields” สามารถอ่านเพิ่มเติมได้ที่ Docker Compose's documentation และเราต้องประกาศ version: "3.4" หรือมากกว่านั้นถึงจะสามารถใช้งาน x- ได้

แทนที่ค่าเดิมของ anchor values ใน service

จากตัวอย่างผมต้องการแก้ไขค่า stop_grace_period ใน worker service สามารถทำได้ดังนี้

worker:
    <<: *default-app
    stop_grace_period: "10s"

ซึ่งถ้าเราเขียนแบบนี้จะเป็นการ "merge" หรือแทนที่ค่าใหม่ให้ทันที

Happy Docker :)

Thanks: https://nickjanetakis.com/blog/docker-tip-82-using-yaml-anchors-and-x-properties-in-docker-compose