Use of template placeholders for binding volumes in Docker Swarm

Viewed 392

I have swarm consisting of 5 nodes. All the nodes have a shared folder /data/shared (over GlusterFS). I want each container's /conf and /data folders to be mounted in their corresponding shared folder (defined by their slot number).

version: '3.7'

services:
  hello:
    image: bash
    hostname: "hello-{{.Task.Slot}}"
    volumes:
      - conf-vol:/conf
      - data-vol:/data
    command:
      >
      bash -c "echo ""hostname: $$(hostname)"" > /conf/hello 
      && echo ""hostname: $$(hostname)"" > /data/hello"
     
    deploy:      
      replicas: 5
      restart_policy:
        condition: none

volumes:
  conf-vol:
    driver_opts:
      type: "ext4"
      o: "bind"
      device: "/data/shared/hello/{{.Task.Slot}}/conf"

  data-vol:
    driver_opts:
      type: "ext4"
      o: "bind"
      device: "/data/shared/hello/{{.Task.Slot}}/data"

Unfortunately, it seems that the {{.Task.Slot}} number of the bound volume does not correspond to the number used for the creation of the container hello-{{.Task.Slot}} (hostname).

cat /data/shared/hello/1/conf/hello 
hostname: hello-5

cat /data/shared/hello/2/conf/hello 
hostname: hello-2

cat /data/shared/hello/3/conf/hello 
hostname: hello-1

cat /data/shared/hello/4/conf/hello 
hostname: hello-3

cat /data/shared/hello/5/conf/hello 
hostname: hello-4

Is there a way to achieve the right binding ?

docker version 
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
1 Answers

Actually it is possible to declare volumes having valid template placeholders on the fly as part of the service declaration as follows:

version: '3.7'

services:
  hello:
    image: bash
    hostname: "hello-{{.Task.Slot}}"
    volumes:
      - /data/shared/hello/{{.Task.Slot}}/conf:/conf
      - /data/shared/hello/{{.Task.Slot}}/data:/data
    command:
      >
      bash -c "echo ""hostname: $$(hostname)"" > /conf/hello 
      && echo ""hostname: $$(hostname)"" > /data/hello"
     
    deploy:      
      replicas: 5
      restart_policy:
        condition: none

The advantage of the named volumes is that they can be reused across multiple services (and are easily retrieved and inspected using the docker command line) but unfortunately they don't work with the template placeholders.

Related