Docker swarm 尝试解析我的 compose 文件中 ENV 变量的值(因为它有一个 go 模板)并给我一个错误
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
错误
我尝试启动一个 logspout 容器并通过 docker-compose 文件设置日志格式(一个 ENV 变量)。不太难,如果我用 docker-compose up
启动它,一切正常。但是当我尝试使用 docker swarm init
和 docker stack deploy -c docker-compose.yml mystack
启动它时,我得到一个错误:
来自守护程序的错误响应:rpc 错误:code = InvalidArgument desc = 扩展环境失败:扩展环境 "RAW_FORMAT={ \"container\" : \"{{ .Container.Name }} \", \"labels\": {{ toJSON .Container.Config.Labels }}, \"timestamp\": \"{{ .Time.Format \"2006-01-02T15:04:05Z07 :00\" }}\", \"source\" : \"{{ .Source }}\", \"message\": {{ toJSON .Data }} }": 模板: expansion:1: 函数"toJSON"未定义
我的理解
我想我只有 swarm 有错误,而不是 docker-compose,因为我想传递给 logspout 的 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 }} }'
此 ENV 变量包含一个 go 模板。但是有了集群模式,你可以create services using go-templates。因此,似乎 swarm 尝试(但失败了)解析我只想传递给 logspout 容器的 ENV 变量的值。
我的问题
这是告诉 swarm 不要解析我的 RAW_FORMAT 变量中的 go-template 的方法吗?
如果不是,是否有其他方法可以将此变量设置为正确的值?
更多...
如果您想重现这个问题,这里有一个最小的 docker-compose 文件:
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 }} }'
如果你在windows,你必须先执行$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1
。
在 go 模板中,可以使用 {{"{{"}}
转义 {{
,因此您的 yml 文件应如下所示:
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 }} }'
你可以通过 {{`
字符串 `}}
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 }} }`}}'
另一个例子
LDAP_SEARCH_FILTER={{`(sAMAccountName={{username}})`}}
错误
我尝试启动一个 logspout 容器并通过 docker-compose 文件设置日志格式(一个 ENV 变量)。不太难,如果我用 docker-compose up
启动它,一切正常。但是当我尝试使用 docker swarm init
和 docker stack deploy -c docker-compose.yml mystack
启动它时,我得到一个错误:
来自守护程序的错误响应:rpc 错误:code = InvalidArgument desc = 扩展环境失败:扩展环境 "RAW_FORMAT={ \"container\" : \"{{ .Container.Name }} \", \"labels\": {{ toJSON .Container.Config.Labels }}, \"timestamp\": \"{{ .Time.Format \"2006-01-02T15:04:05Z07 :00\" }}\", \"source\" : \"{{ .Source }}\", \"message\": {{ toJSON .Data }} }": 模板: expansion:1: 函数"toJSON"未定义
我的理解
我想我只有 swarm 有错误,而不是 docker-compose,因为我想传递给 logspout 的 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 }} }'
此 ENV 变量包含一个 go 模板。但是有了集群模式,你可以create services using go-templates。因此,似乎 swarm 尝试(但失败了)解析我只想传递给 logspout 容器的 ENV 变量的值。
我的问题
这是告诉 swarm 不要解析我的 RAW_FORMAT 变量中的 go-template 的方法吗?
如果不是,是否有其他方法可以将此变量设置为正确的值?
更多...
如果您想重现这个问题,这里有一个最小的 docker-compose 文件:
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 }} }'
如果你在windows,你必须先执行$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1
。
在 go 模板中,可以使用 {{"{{"}}
转义 {{
,因此您的 yml 文件应如下所示:
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 }} }'
你可以通过 {{`
字符串 `}}
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 }} }`}}'
另一个例子
LDAP_SEARCH_FILTER={{`(sAMAccountName={{username}})`}}