10

Right now, I have two-node in swarm cluster

$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
yey1njv9uz8adf33m7oz0h80f *   redis2              Ready               Active              Leader
lbo91v2l15h24isfd5jegoxu1     redis3              Ready               Active   

this is docker-compose.yml file

version: "3"
services:
  daggr:
    # replace username/repo:tag with your name and image details
    image: daggr
    hostname: examplehostname
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "4000:80"
    networks:
      - webnet
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
        - "8080:8080"
    volumes:
        - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
        placement:
            constraints: [node.role == manager]
    networks:
        - webnet
  redis:
    image: redis
    networks:
        - webnet
networks:
  webnet:

as you see, i am explictly setting hostname for daggr service

daggr container basically runs a python tornado web server

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('Hello from daggr running on %s\n' % socket.gethostname())

I've tested out as below

$ curl redis2:4000
Hello from daggr running on examplehostname

Now, instead of statically setting the hostname, i want it to be dynamic matching to hostname of where the container is running. ie. if daggr container is running on redis2 it should say redis2 and on redis3, it should say redis3.

How can i specify that from docker-compose.yml file?

ealeon
  • 12,074
  • 24
  • 92
  • 173
  • Why do you need this? – Constantin Galbenu Apr 05 '18 at 07:09
  • @ConstantinGalbenu it's a requirement set by the users that they need to be able to know which host the daggr container is running as daggr containers can run anywhere in the swarm cluster. For example, what if docker host is having a hung mount and daggr web is hung, they need to be able to know which host that is – ealeon Apr 05 '18 at 07:12

3 Answers3

10

If you are running at least Docker 17.10 then you can use something like this:

services:
  daggr:
    hostname: '{{.Node.Hostname}}'

See this for more information.

Constantin Galbenu
  • 16,951
  • 3
  • 38
  • 54
  • 6
    I'm using Docker 19.03.5 and this syntax does not work at all from docker-compose, it just gets interpreted as a string literal with the curly braces stripped out. Am I doing something wrong? – Oly Dungey Mar 11 '20 at 14:38
  • 1
    This is a swarm feature. Node makes only sense in the context of swarm. See my question from a couple weeks ago. https://stackoverflow.com/questions/64620078/template-placerholder-in-compose-service-definition-environment-array – The Fool Nov 28 '20 at 01:04
  • this did not worked for me on latest docker in swarm mode. – Chang Zhao Dec 18 '21 at 19:09
3

The selected answer above did not work for me (presumably since I am not running docker/docker-compose in swarm mode).

I was able to set the container hostname for my reverse proxy to match the docker host FQDN by doing the following:

version: '3'

reverse-proxy:
  hostname: $HOSTNAME

This allowed me to easily configure Nginx to pick the correct server cert / key pair prior to startup.

brandonsimpkins
  • 546
  • 1
  • 3
  • 13
  • 7
    Where's `$HOSTNAME` defined? – Abhijit Sarkar Nov 21 '18 at 23:03
  • 1
    Note: interpolation happens on the machine this is run on for variable substitution. The question specifically mentions being apart of a swarm, so this answer would set the hostname of the service to the hostname of the node this is run on for each task created. – 404 Apr 24 '19 at 17:47
2

I tried Constantin Galbenu's solution only work on a swarm setup and brandonsimpkins's lacks the HOSTNAME definition.

A workaround is to set an environment variable to your hostname:

export HOSTNAME="$(cat /etc/hostname)"
my-container:
  hostname: ${HOSTNAME}

If like me, your hostname is the same as your username, skip step 1 and only do

my-container:
  hostname: ${USER}
David Bensoussan
  • 2,887
  • 2
  • 38
  • 55