DevToolBox免费
博客

Docker Compose YAML 验证:10 个常见语法错误及修复方法

9 分钟阅读作者 DevToolBox
Ad Space

Docker Compose 的 YAML 文件看起来简单,出错时却很难排查。多一个空格、缩进层级错误或未加引号的特殊字符,都会产生晦涩的错误信息。下面整理 10 个最常见错误 及对应的修复方法。

使用 JSON-YAML 转换器验证 YAML →

错误 1:用 Tab 代替空格

错误信息:

yaml: line 5: found a tab character where an indentation space is expected

问题: YAML 严格禁止使用 Tab 做缩进,这是最常见的错误之一。

修复: 将所有 Tab 替换为空格(通常每级 2 个空格)。

# BAD (tabs - invisible but breaks YAML)
services:
	web:
		image: nginx

# GOOD (2 spaces)
services:
  web:
    image: nginx

编辑器提示: 在编辑器中开启「显示空白字符」,可区分 Tab 和空格。VS Code:设置 → Render Whitespace → "all"。

错误 2:缩进不一致

错误信息:

yaml: line 8: mapping values are not allowed in this context

问题: 混用不同缩进(例如部分用 2 个空格,部分用 4 个)。

# BAD (inconsistent: 2 spaces then 4 spaces)
services:
  web:
      image: nginx     # 4 spaces - inconsistent!
      ports:
        - "80:80"

# GOOD (consistent 2 spaces)
services:
  web:
    image: nginx       # 2 spaces - consistent
    ports:
      - "80:80"

错误 3:值中未加引号的特殊字符

错误信息:

yaml: line 6: did not find expected key

问题: YAML 会特殊解析冒号、井号和花括号等,需加引号。

# BAD
services:
  web:
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb  # colon in value!
      - APP_TITLE=My App: The Best                       # colon in value!

# GOOD (quote values with special characters)
services:
  web:
    environment:
      - "DATABASE_URL=postgres://user:pass@db:5432/mydb"
      - "APP_TITLE=My App: The Best"

需要加引号的字符: : { } [ ] , & * # ? | - < > = ! % @

错误 4:端口映射格式错误

错误信息:

services.web.ports contains an invalid type, it should be a number, or an object

问题: YAML 可能将未加引号的 80:80 等解释为 base-60 数字。

# RISKY (YAML may interpret as base-60)
services:
  web:
    ports:
      - 80:80        # Works but risky
      - 5432:5432    # May cause issues

# SAFE (always quote port mappings)
services:
  web:
    ports:
      - "80:80"
      - "5432:5432"
      - "127.0.0.1:3000:3000"

错误 5:version 键缺失或错误

错误信息:

(root) Additional property version is not allowed

问题: Docker Compose v2 不再要求或接受 version 键。

# OUTDATED (Docker Compose v1 format)
version: "3.8"
services:
  web:
    image: nginx

# CURRENT (Docker Compose v2 - no version needed)
services:
  web:
    image: nginx

若使用 docker compose(v2,带空格),删除 version。若使用 docker-compose(v1,带连字符),保留。

错误 6:环境变量 mapping 与 list 混用

错误信息:

services.web.environment must be a mapping or an array

问题: 环境变量混用了 mapping 和 list 两种语法。

# Format A: List (with dashes)
services:
  web:
    environment:
      - NODE_ENV=production
      - PORT=3000

# Format B: Mapping (key: value)
services:
  web:
    environment:
      NODE_ENV: production
      PORT: 3000

# BAD: Mixing both formats
services:
  web:
    environment:
      NODE_ENV: production
      - PORT=3000          # ERROR: mixing formats!

错误 7:布尔值未加引号

错误信息: 无显式报错,但行为异常。

问题: YAML 会把 yes、no、true、false、on、off 解析为布尔值,而非字符串。

# BAD (YAML converts to boolean true/false)
services:
  web:
    environment:
      FEATURE_FLAG: yes       # becomes boolean true, not string "yes"
      DEBUG: on               # becomes boolean true
      COUNTRY: NO             # becomes boolean false (Norway code!)

# GOOD (quote string values)
services:
  web:
    environment:
      FEATURE_FLAG: "yes"
      DEBUG: "on"
      COUNTRY: "NO"

错误 8:重复的键

错误信息: 通常不报错,第二个值会静默覆盖第一个。

# BAD (duplicate 'ports' key - second one silently wins)
services:
  web:
    image: nginx
    ports:
      - "80:80"
    environment:
      - NODE_ENV=production
    ports:                    # DUPLICATE! This replaces the first ports
      - "443:443"

# GOOD (combine under single key)
services:
  web:
    image: nginx
    ports:
      - "80:80"
      - "443:443"
    environment:
      - NODE_ENV=production

错误 9:卷路径映射问题

错误信息:

services.web.volumes contains an invalid type

问题: Windows 路径若带反斜杠且未加引号,易出问题。

# BAD (Windows paths without quotes)
services:
  web:
    volumes:
      - C:\Users\me\app:/app     # Backslashes cause issues

# GOOD (use forward slashes or quotes)
services:
  web:
    volumes:
      - "./app:/app"
      - "/home/user/data:/data"
      - "C:/Users/me/app:/app"      # Forward slashes on Windows

错误 10:YAML 锚点使用不当

错误信息:

yaml: unknown anchor 'common'

问题: 在定义锚点(&name)之前就引用它(*name)。

# BAD (reference before definition)
services:
  web:
    <<: *common          # ERROR: 'common' not defined yet

x-common: &common
  restart: always

# GOOD (define anchor first, then reference)
x-common: &common
  restart: always
  logging:
    driver: json-file

services:
  web:
    <<: *common
    image: nginx
  api:
    <<: *common
    image: node:20

快速校验清单

运行 docker compose up 前请确认:

  1. 执行 docker compose config 校验语法
  2. 检查是否包含 Tab: grep -P '\t' docker-compose.yml
  3. 所有端口映射都加引号
  4. 同一层级无重复键
  5. 含特殊字符的值都加引号
  6. 缩进一致(建议 2 空格)

使用 JSON-YAML 转换器验证 YAML →

格式化 "docker compose config" 的 JSON 输出 →

常见问题

运行前如何验证 Docker Compose 文件?

执行 "docker compose config"(v1 为 "docker-compose config")可验证并显示解析后的配置。该命令会解析 YAML、解析变量并显示语法错误。也可使用在线 YAML 校验或我们的 JSON-YAML 转换工具。

Docker Compose 报 "service must be a mapping" 或 "services must be a mapping" 是什么意思?

表示 services 段(或某个服务)未正确写成 YAML 映射(键值对)。常见原因:服务名下方缩进错误、在需要 mapping 的地方使用了 list(-)、或结构拼写错误。

Docker Compose YAML 应使用 Tab 还是空格?

应始终使用空格。YAML 不允许用 Tab 做缩进,这是 YAML 解析错误的首要原因。建议在编辑器中把 Tab 映射为插入 2 个空格。

试试这些相关工具

Y{}JSON ↔ YAML Converter{ }JSON Formatter
Ad Space

相关文章

Serverless 平台的 Cron 调度:GitHub Actions、Vercel Cron 和 Cloudflare Workers

掌握各 Serverless 平台的 Cron 表达式,了解语法差异、时区陷阱和实用调度示例。