Alessandro Dionisi
Alessandro Dionisi

Reputation: 2684

Host environment variables with docker stack deploy

I was wondering if there is a way to use environment variables taken from the host where the container is deployed, instead of the ones taken from where the docker stack deploy command is executed. For example imagine the following docker-compose.yml launched on three node Docker Swarm cluster:

version: '3.2'
services:
  kafka:
    image: wurstmeister/kafka
    ports:
      - target: 9094
        published: 9094
        protocol: tcp
        mode: host
    deploy:
      mode: global
    environment:
      KAFKA_JMX_OPTS: "-Djava.rmi.server.hostname=${JMX_HOSTNAME} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.rmi.port=1099"

The JMX_HOSTNAME should be taken from the host where the container is actually deployed and should not be the same value for every container. Is there a correct way to do this?

Upvotes: 20

Views: 26676

Answers (3)

B. Bilgin
B. Bilgin

Reputation: 783

I found another way for when you have many environment variables. The same method also works with docker-compose up

sudo -E docker stack deploy -c docker-compose.yml mystack

instead of

env foo="${foo}" bar="${bar}" docker stack deploy -c docker-compose.yml mystack

sudo -E man description;

   -E, --preserve-env
               Indicates to the security policy that the user wishes to
               preserve their existing environment variables.  The
               security policy may return an error if the user does not
               have permission to preserve the environment.

Upvotes: 5

Tim
Tim

Reputation: 1805

It works if you run the docker command through env.

env JMX_HOSTNAME="${JMX_HOSTNAME}" docker stack deploy -c docker-compose.yml mystack

Credit to GitHub issue that pointed me in the right direction.

Upvotes: 7

Bret Fisher
Bret Fisher

Reputation: 8596

Yes, this works when you combine two concepts:

  1. Swarm node labels, of which Hostname is one of the built-in ones.
  2. Swarm service go templates, which also work in stack files.

This would pull in the hostname to the ENV value of DUDE for each container to be the host that it's running on:

version: '3.4'

services:
  nginx:
    image: nginx
    environment:
      DUDE: "{{.Node.Hostname}}"
    deploy:
      replicas: 3

Upvotes: 33

Related Questions