Docker swarm tries to parse the value of ENV variable in my compose file (because it has a go template in it) and gives me an error

时光怂恿深爱的人放手 提交于 2019-12-11 01:29:52

问题


The error

I try to launch a logspout container and set the log format (an ENV variable) via a docker-compose file. Not too difficult, and if I launch it with docker-compose up, everything works fine. But when I try to launch it with docker swarm init and docker stack deploy -c docker-compose.yml mystack, I get an error:

Error response from daemon: rpc error: code = InvalidArgument desc = expanding env failed: expanding env "RAW_FORMAT={ \"container\" : \"{{ .Container.Name }}\", \"labels\": {{ toJSON .Container.Config.Labels }}, \"timestamp\": \"{{ .Time.Format \"2006-01-02T15:04:05Z07:00\" }}\", \"source\" : \"{{ .Source }}\", \"message\": {{ toJSON .Data }} }": template: expansion:1: function "toJSON" not defined

What I understand

I think I have the error only with swarm and not docker-compose, because the ENV variable I want to pass to logspout is:

RAW_FORMAT: '{ "container" : "{{ .Container.Name }}", "labels": {{ toJSON .Container.Config.Labels }}, "timestamp": "{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{ .Source }}", "message": {{ toJSON .Data }} }'

This ENV variable contains a go template. But with swarm mode, you can create services using go-templates. So it seems that swarm tries (and fails) to parse the value of the ENV variable that I just want to pass to the logspout container.

My question

  1. Is it a way to tell swarm not to parse the go-template in my RAW_FORMAT variable?

  2. If not, is there an other way to set this variable to the correct value?

More...

If you want to reproduce this problem, here is a minimal docker-compose file:

version: "3.3"
services:
logspout:
  image: gliderlabs/logspout:latest
  volumes:
    - /etc/hostname:/etc/host_hostname:ro
    - /var/run/docker.sock:/var/run/docker.sock
  environment:
    RAW_FORMAT: '{ "container" : "{{ .Container.Name }}", "labels": {{ toJSON .Container.Config.Labels }}, "timestamp": "{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{ .Source }}", "message": {{ toJSON .Data }} }'

If you are on windows, you have to execute $Env:COMPOSE_CONVERT_WINDOWS_PATHS=1 first.


回答1:


In go templates, escaping {{ can be done with {{"{{"}}, so your yml file should look like this:

version: "3.3"
services:
  logspout:
    image: gliderlabs/logspout:latest
    volumes:
      - /etc/hostname:/etc/host_hostname:ro
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      RAW_FORMAT: '{ "container" : "{{"{{"}} .Container.Name }}", "labels": {{"{{"}} toJSON .Container.Config.Labels }}, "timestamp": "{{"{{"}} .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{"{{"}} .Source }}", "message": {{"{{"}} toJSON .Data }} }'



回答2:


You can warp by {{` string `}}

  environment:
    RAW_FORMAT: '{{`{ "container" : "{{ .Container.Name }}`}}", "labels": {{ toJSON .Container.Config.Labels }}, "timestamp": "{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{ .Source }}", "message": {{ toJSON .Data }} }`}}'

Another example

LDAP_SEARCH_FILTER={{`(sAMAccountName={{username}})`}}


来源:https://stackoverflow.com/questions/52855230/docker-swarm-tries-to-parse-the-value-of-env-variable-in-my-compose-file-becaus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!