能否通过ARG向Dockerfile传递多条CMD命令?
实现Docker容器依次执行多条命令的可行方案
你的需求完全可以实现,先分析你遇到的两个错误原因,再给出正确写法:
错误原因分析
第一种写法报错:
CMD "${COMMAND}"
这种写法属于Docker的shell格式CMD误用,Docker会把整个"echo 1; echo 2"当作一个完整的命令名去系统路径中查找,而非交给shell解析分号分隔的命令序列,因此出现/bin/sh: echo 1; echo 2: not found的错误。第二种写法输出不符合预期:
CMD ["sh", "-c", "${COMMAND}"]
这里用了exec格式CMD,Docker在构建时会直接将ARG的COMMAND值替换到${COMMAND}位置,但如果变量替换后的字符串未被shell正确解析,或参数传递存在转义问题,会导致sh把整个命令序列当作echo的参数,只输出1; echo 2。
正确实现方式
方式一:依赖运行时环境变量(shell格式CMD)
修改Dockerfile,让shell负责解析命令序列和环境变量:
FROM alpine ARG COMMAND ENV COMMAND=${COMMAND} CMD sh -c "$COMMAND"
docker-compose.yml保持不变,构建运行后,容器会启动shell并执行$COMMAND环境变量中的命令序列,依次输出1和2。
方式二:构建时直接注入命令序列(exec格式CMD)
调整Dockerfile,让构建时直接将命令序列注入exec格式的CMD:
FROM alpine ARG COMMAND CMD ["sh", "-c", "${COMMAND}"]
这种写法下,构建过程中ARG的COMMAND值会直接替换${COMMAND},最终CMD被生成为["sh", "-c", "echo 1; echo 2"],运行时sh会正确解析分号,依次执行两个echo命令。
内容的提问来源于stack exchange,提问作者Vulwsztyn
相关产品推荐
相关产品推荐

