为什么 docker-compose 不能在 JSON 兼容模式下使用选项卡?

Dav*_* M. 3 json yaml docker docker-compose

在使用 时docker-compose,我宁愿使用 JSON 而不是 YAML,并且根据Docker 提供官方文档,可以使用它:

在此处输入图片说明

也就是说,当我尝试运行一个简单的 compose 兼容 JSON 文件时,它失败并显示以下输出:

ERROR: yaml.scanner.ScannerError: while scanning for the next token
found character '\t' that cannot start any token
  in "./sample-file.json", line 2, column 1
Run Code Online (Sandbox Code Playgroud)

但是,如果我用空格替换制表符,无论有多少(即使没有一个空格),它都会开始工作:

Starting sandbox_apache_1 ... done
Attaching to sandbox_apache_1
apache_1  | AH00558: httpd: Could not reliably...
Run Code Online (Sandbox Code Playgroud)

在图片中它清楚地表明“所以任何JSON 文件”,这似乎是不真实的。

那这又是怎么回事?

Ant*_*hon 5

TL:DR:docker-compose当他们使用基于 YAML 1.1 的加载器加载他们的.yml文件时,文档在引用 YAML 1.2 的一个特性时会产生误导。

当您删除 TAB 时,事情会起作用是因为您基本上可以拥有非常紧凑的 JSON:{"a":[1,2,3]}节点之间根本没有任何空格。


是的,YAML 是用于所有实际目的的 JSON 超集,但您需要记住一些事项。

首先,您应该使用没有正确编写首字母缩略词(Yaml 而不是 YAML)并且不直接引用规范的文档,而是引用一个带有一丝盐分的非权威文档。此外,该文件使用扩展.ymldocker-compose.yml文件,虽然文件YAML推荐的文件扩展名,根据对yaml.org的常见问题,一直是.yaml自2006年九月

YAML 1.2 的规范声明它旨在作为 JSON 的超集,但docker-compose使用 PyYAML 来解析/加载 YAML 文件,并且仅加载 YAML 1.1 的一个子集。从 1.1 到 1.2,对 YAML 进行了特定更改,使 YAML 1.2 更多但不是 100% 的 JSON 超集。

YAML 1.2 中允许使用 TAB 字符作为空格,只要这不是决定缩进的空格。由于 JSON 是流样式的 YAML,其中缩进不重要,您可以阅读它,因为在初始{[.

在 YAML 1.1 中,对使用 TAB限制更加严格

标量内容之外的被忽略的空格字符。这些空格用于标记之间的缩进和分隔。为了保持可移植性,在这些情况下不得使用制表符,因为不同的系统对制表符的处理方式不同。

(即,您可以在 YAML 1.1 中的非普通标量中使用 TAB 字符)。