在Docker中运行带命令行参数的Go程序报错,如何解决?
解决Docker运行时命令行参数传递错误的问题
问题场景
我编写了一个接收命令行参数的Go程序,尝试用Docker构建并运行,但执行运行命令时出现错误。相关文件及操作如下:
main.go
package main import ( "fmt" "os" ) func main() { if len(os.Args) > 2 { fmt.Println("arg: ", os.Args[1]) } else { fmt.Println("no args") } }
Dockerfile
FROM golang:latest COPY . /tmp WORKDIR /tmp RUN go build -o app main.go CMD [ "./app" ]
构建与运行命令
构建命令:
sudo docker build -t test .
运行命令:
sudo docker run test arg1
错误信息
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "arg1": executable file not found in $PATH: unknown. ERRO[0002] error waiting for container:
错误原因
Docker的docker run命令后跟随的参数,会直接替换Dockerfile中CMD定义的整个命令。这里输入arg1后,容器会尝试直接执行arg1这个不存在的可执行文件,而非将其作为./app的参数,因此报错。
解决方案
有两种可行的解决方式:
方式一:修改运行命令,明确指定程序与参数
将运行命令改为以下形式,直接传入完整的执行命令和参数:
sudo docker run test ./app arg1
此时Docker会执行./app arg1,arg1会被正确识别为程序的命令行参数。
方式二:修改Dockerfile,用ENTRYPOINT固定执行程序
修改Dockerfile中的CMD为ENTRYPOINT,或结合ENTRYPOINT与CMD设置默认参数:
FROM golang:latest COPY . /tmp WORKDIR /tmp RUN go build -o app main.go ENTRYPOINT [ "./app" ] CMD [ "" ] # 设置默认无参数,也可留空
修改后,运行docker run test arg1时,arg1会自动作为ENTRYPOINT指定的./app的参数,不会替换执行程序。
验证
执行正确的运行命令后,程序输出:
arg: arg1
若不传递参数,执行sudo docker run test(方式二)或sudo docker run test ./app(方式一),输出:
no args
内容的提问来源于stack exchange,提问作者12iq
相关产品推荐
相关产品推荐

