Why does this variable interpolation work?

Starting with the default job file, I made some minor changes, an lo-behold it works!
Changing the Consul key also successfully restarts the container.

My question is … “Why?”. Where in documentation does it say that this would work?

I have been searching a lot of the docs to find this specific mention as to why a template based environment variable can be referenced like this in the docker tag.

job "redis" {
  datacenters = ["dc1"]

  group "cache" {
    network {
      port "db" {
        to = 6379

    task "redis" {
      driver = "docker"

      config {
        image          = "redis:${DOCKER_TAG}"
        auth_soft_fail = true

        ports = ["db"]

      template {
        data = <<EOH
DOCKER_TAG="{{key "service/redis/tag"}}"

        destination = "local/file.env"
        env         = true

      resources {
        cpu    = 500
        memory = 256

Hi @shantanugadgil :wave:

I think it’s a cascade of operations. When the Consul key changes, the allocation is restarted since you don’t have a change_mode defined.

Since the allocation is recreated, the ${DOCKER_TAG} gets reevaluated and interpolated. You can read more details about this here: Variable Interpolation | Nomad by HashiCorp

Nomad supports interpreting two classes of variables: node attributes and runtime environment variables.

I think that, if you were to use change_mode = "signal" this wouldn’t work since the jobspec won’t be reevaluated.

Is this the information you were looking for?

Hi @lgfa29 my question was only about the $DOCKER_TAG bit. (not that I am complaining, I am pleasantly happy)
i.e. As I hadn’t seen an actual example of this anywhere in docs, so I wasn’t sure it would have worked, that’s all.

I have already been using the other (Consul Template) functionalities for quite a few years now :slight_smile:

The variable interpolation link mentions the ${attr......} variables, also the ${NOMAD_...} variables are sort of “known” to be visible in the “env”.

The fact that: “a variable fetched from Consul, then injected into the environment”, could be visible to the “pull” operation was not obvious to me when reading the template and the variable interpolation docs.

When this worked, I thought … “Has this always worked like this?!? I have doing this using a different method unnecessarily”

Guess things like this need more examples! :open_book:

Oh, I am fully aware that you Nomad power user, and probably know more about it than me :grinning_face_with_smiling_eyes:

I was just trying to set the context in case someone with less experience stumbled upon this post.

Ah got it. The NOMAD_* are special, in the sense that they can be interpolated in several other places, like, for example, check -> name. I think that’s why they are the only ones mentioned in the docs.

Other environment variables work in image because I think that string is passed directly to Docker and interpreted by the shell, so it’s more like a happy accident? :sweat_smile:


hi @lgfa29 using the above logic, how I can verify using the nomad cli which docker image is being actually downloaded?

As the job definition has now has a variable, until the allocation succeeds/fails, I am not sure what image:tag is being downloaded.

Of course, I can get the value from the file file.env on the node, but I was wondering if there was a cmd line way of getting this information?

1 Like

Hum…good question. Unfortunately I don’t think it’s possible, since the Nomad agent just passes the raw string to the Docker daemon.

I guess the Docker task driver could render the string before passing it along? :thinking:

This would not update the cluster state though (i.e., changing the env var value would not cause the job to be updated, or the API won’t return the rendered values), but the task driver may be able to emit a better task event.

Could you open a feature request so we can track and discuss this better?


@lgfa29 I ended up opening this:

… but the more I think about this … there should be a separate feature request issue as well, which could show the image:tag for the Docker driver on the default task page of the GUI.


Also opened this: