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
相关产品推荐
相关产品推荐

