Dockerfile中CMD命令执行失败,容器内手动执行正常的原因排查
问题场景与解决分析
初始Dockerfile内容
FROM maven:latest COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN mvn compile && mvn clean install EXPOSE 8000/tcp CMD ["mvn", "exec:java", "-Dexec.mainClass='com.demo.App'", "-e"]
启动失败报错
执行docker run -it --rm <image>后项目启动失败,核心报错:
java.lang.ClassNotFoundException: 'com.demo.App' ... [ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.1.0:java (default-cli) on project javasnippet: An exception occurred while executing the Java class. 'com.demo.App'
容器内手动执行验证
注释CMD后重新构建镜像,进入容器查看目录:
root@c9ed5282e511:/usr/src/myapp# ls Dockerfile pom.xml src target
手动执行命令后项目正常启动:
root@c9ed5282e511:/usr/src/myapp# mvn exec:java -Dexec.mainClass='com.demo.App' -e ... Server started at: Tue Apr 11 09:49:15 UTC 2023
原因与错误分析
核心原因:Docker CMD的数组(exec)格式与shell执行环境的参数解析逻辑不同。
- 在shell环境手动执行时,单引号
'是shell语法符号,用于包裹字符串,shell会自动去掉单引号,实际传递给mvn的参数是-Dexec.mainClass=com.demo.App。 - 而CMD的数组格式中,每个元素直接作为命令参数传递,不会经过shell解析,因此
'-Dexec.mainClass='com.demo.App''里的单引号会被当成参数的一部分,mvn实际收到的类名是带单引号的'com.demo.App',导致找不到对应类。
- 在shell环境手动执行时,单引号
操作错误:使用Docker CMD的数组格式时,错误保留了shell风格的单引号,引发参数传递异常。
修正方案
去掉CMD中的单引号,修改为:
CMD ["mvn", "exec:java", "-Dexec.mainClass=com.demo.App", "-e"]
内容的提问来源于stack exchange,提问作者romlym
相关产品推荐
相关产品推荐

