You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中如何转义healthcheck测试值里的冒号?

Docker Compose中MongoDB健康检查的冒号转义问题

问题场景

尝试为Docker Compose中的MongoDB服务配置健康检查,使用如下YAML配置:

version: '3.8'

services:
    mongodb:
        image: mongo
        container_name: mongodb
        environment:
            - MONGO_INITDB_ROOT_USERNAME=${MONGODB_USER}
            - MONGO_INITDB_ROOT_PASSWORD=${MONGODB_PASS}
        volumes:
            - ./db:/data/db
        networks:
            - proxy
        restart: unless-stopped
        healthcheck:
            test: test $$(echo "rs.initiate({_id: 'rs0', members: [{_id: 1, 'host': 'mongodb:27017'}]}).ok || rs.status().ok" | mongosh -u $${MONGO_INITDB_ROOT_USERNAME} -p $${MONGO_INITDB_ROOT_PASSWORD} --quiet) -eq 1
            interval: 10s
            start_period: 30s

执行时触发YAML解析错误:

yaml: mapping values are not allowed in this context

移除配置中的冒号后可正常运行,需要解决如何转义测试值中的冒号。

解决方法

方法1:用单引号包裹整个test值

将test字段的整个值用单引号包裹,YAML会将其视为纯字符串,不会解析内部的冒号为映射分隔符。注意单引号内部的单引号需要用两个单引号转义:

version: '3.8'

services:
    mongodb:
        image: mongo
        container_name: mongodb
        environment:
            - MONGO_INITDB_ROOT_USERNAME=${MONGODB_USER}
            - MONGO_INITDB_ROOT_PASSWORD=${MONGODB_PASS}
        volumes:
            - ./db:/data/db
        networks:
            - proxy
        restart: unless-stopped
        healthcheck:
            test: 'test $$(echo "rs.initiate({_id: ''rs0'', members: [{_id: 1, ''host'': ''mongodb:27017''}]}).ok || rs.status().ok" | mongosh -u $${MONGO_INITDB_ROOT_USERNAME} -p $${MONGO_INITDB_ROOT_PASSWORD} --quiet) -eq 1'
            interval: 10s
            start_period: 30s

方法2:使用数组格式定义test

Docker Compose支持以数组形式定义健康检查的test字段,每个命令片段作为数组元素,避免YAML解析器误判冒号:

version: '3.8'

services:
    mongodb:
        image: mongo
        container_name: mongodb
        environment:
            - MONGO_INITDB_ROOT_USERNAME=${MONGODB_USER}
            - MONGO_INITDB_ROOT_PASSWORD=${MONGODB_PASS}
        volumes:
            - ./db:/data/db
        networks:
            - proxy
        restart: unless-stopped
        healthcheck:
            test:
              - test
              - $$(echo "rs.initiate({_id: 'rs0', members: [{_id: 1, 'host': 'mongodb:27017'}]}).ok || rs.status().ok" | mongosh -u $${MONGO_INITDB_ROOT_USERNAME} -p $${MONGO_INITDB_ROOT_PASSWORD} --quiet)
              - -eq
              - 1
            interval: 10s
            start_period: 30s

原因说明

YAML语法中,未被引号包裹的字符串里,冒号后紧跟空格时会被解析为键值对的分隔符。你的健康检查命令中,host: 'mongodb:27017'里的冒号虽然在双引号内,但外层整个字符串未加引号,YAML解析器会提前识别到冒号并尝试解析为映射,从而抛出错误。通过包裹引号或改用数组格式,可避免这个解析问题。

内容的提问来源于stack exchange,提问作者Finsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:01:57