Using YAML anchors & aliases on docker-compose.yml

One of the most forgotten feature of the YAML files is the usage of templates in order to decrease the copy&paste effect on them. And yes, it’s a feature of YAML files, not from docker.

Repeated code is always considered a very bad practice, but configuration files & other scripts are always ignored on the already accepted as good practices in development circles.

Why?

On very dimple docker-compose.yml files, usually with only one service, usually there is no need for this feature. For example:

version: '3.7'
services:
  anthill:
    image: ociotec/anthill:1.0.0
    ports:
      - '80'
    networks:
      - proxy_net
    deploy:
      placement:
        constraints:
          - node.labels.arch == x86
      labels:
        traefik.enable: 'true'
        traefik.port: '80'
        traefik.docker.network: 'proxy_net'
        traefik.frontend.rule: 'Host: anthill.eht.ociotec.com'
networks:
  proxy_net:
    external: true

But when you have to define several services with same network definitions, maybe placement constrains, labels… YAML anchors & labels start to shine as a useful tool.

Now imagine that you want to add a second service really similar to the first one:

version: '3.7'
services:
  anthill:
    image: ociotec/anthill:1.0.0
    ports:
      - '80'
    networks:
      - proxy_net
    deploy:
      placement:
        constraints:
          - node.labels.arch == x86
      labels:
        traefik.enable: 'true'
        traefik.port: '80'
        traefik.docker.network: 'proxy_net'
        traefik.frontend.rule: 'Host: anthill.eht.ociotec.com'
  conway:
    image: ociotec/conway:1.0.0
    ports:
      - '80'
    networks:
      - proxy_net
    deploy:
      placement:
        constraints:
          - node.labels.arch == x86
networks:
  proxy_net:
    external: true

On this example the only difference is the service name, image & one of the deployment labels, the rest is completely repeated.

The solution

A code snippet is the best description:

version: '3.7'
services:
  anthill: &service
    image: ociotec/anthill:1.0.0
    ports:
      - '80'
    networks:
      - proxy_net
    deploy:
      placement:
        constraints:
          - node.labels.arch == x86
      labels: &labels
        traefik.enable: 'true'
        traefik.port: '80'
        traefik.docker.network: 'proxy_net'
        traefik.frontend.rule: 'Host: anthill.eht.ociotec.com'
  conway:
    <<: *service
    image: ociotec/conway:1.0.0
    deploy:
      <<: *deploy
      labels:
        <<: *labels
        traefik.frontend.rule: 'Host: conway.eht.ociotec.com'
networks:
  proxy_net:
    external: true

The magic:

  • COPY: anchors are defined with & symbol after the element to copy; in the previous example there are 3 anchors:
    • one for the full service anthill,
    • one for the deploy section,
    • and other for the deployment labels.
  • PASTE: labels are defined with <<: * symbol, they should use the same name than the anchor; in the previous example there are 3 labels:
    • one for copying the full service definition into conway service,
    • one for the deploy section,
    • and other to copy the deployment labels.

The idea is that in the “repeated” service we only introduce what is different, take care than you could be tempted to omit the second and third anchors/labels but they are needed because we are redefining the the placement label traefik.frontend.rule.

If they were omitted the YAML syntax interprets that you don’t need placement section and the first 3 labels, something like this:

...
  conway:
    image: ociotec/conway:1.0.0
    ports:
      - '80'
    networks:
      - proxy_net
    deploy:
      labels:
        traefik.frontend.rule: 'Host: conway.eht.ociotec.com'
...

Conclusions

Once you start to define a lot of docker-compose.yml files you will find yourself repeating again and again the content of the file.

One day you realize you found & fixed one bug in one of the services but you missed other service in the same file.

By the way, the services used in this example are online, they are cellular automatons that I have developed myself, they are available here:


Useful resources

Leave a Reply

Your email address will not be published. Required fields are marked *