使用docker-compose运行带delve的Go二进制文件报错:无此文件或目录
问题:Docker Compose运行带Delve调试的Go程序启动失败
错误信息
ERROR: for nft-overseer Cannot start service nft-overseer: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "dlv --listen=:${dlv_port} --headless=true --api-version=2 --accept-multiclient exec ./main": stat dlv --listen=:${dlv_port} --headless=true --api-version=2 --accept-multiclient exec ./main: no such file or directory: unknown
问题原因
- CMD格式错误:Dockerfile中使用JSON数组格式的
CMD时,将整个调试命令作为单个字符串传入,Docker会尝试寻找名为dlv --listen=${dlv_port} ...的可执行文件,而非将dlv作为命令、后续内容作为参数。 - 环境变量未传递:构建阶段的
ARG dlv_port仅在镜像构建时有效,容器运行时无法直接引用,需转为环境变量才能展开。
解决步骤
1. 修改Dockerfile配置
方案一:使用Shell格式CMD(推荐,自动处理变量展开)
FROM golang:1.19.1-alpine3.16 as builder RUN apk --no-cache --update --upgrade add git alpine-sdk ENV GO111MODULE on ENV CGO_ENABLED 1 WORKDIR /app COPY . . RUN go mod download RUN go build -gcflags "all=-N -l" ./cmd/main FROM golang:1.19.1-alpine3.16 RUN apk --no-cache --update --upgrade add curl RUN go install github.com/go-delve/delve/cmd/dlv@v1.20.1 ARG config_file ARG dlv_port # 将构建参数转为运行时环境变量 ENV DLV_PORT=${dlv_port} WORKDIR /app COPY configs/${config_file:-config.yaml} configs/config.yaml COPY --from=0 /app/main . # Shell格式CMD自动展开环境变量 CMD dlv --listen=:${DLV_PORT} --headless=true --api-version=2 --accept-multiclient exec ./main
方案二:使用拆分参数的JSON格式
若坚持用JSON格式,需将命令和每个参数拆分为独立数组元素,同时通过Shell处理变量展开:
# ... 其余内容同上 ... ENV DLV_PORT=${dlv_port} CMD ["sh", "-c", "dlv --listen=:${DLV_PORT} --headless=true --api-version=2 --accept-multiclient exec ./main"]
2. 重新启动容器
执行原启动命令重新构建并运行:
CONFIG=$CONFIG DLV_PORT=2000 DOCKER_FILE=Dockerfile_dlv docker-compose up --build --force-recreate -d
额外验证点
- 确认
dlv安装路径在容器PATH中:golang镜像默认将go install的目标路径/go/bin加入PATH,无需额外配置。 - 检查Docker Compose端口映射:确保
10883:${DLV_PORT:-2000}的端口与调试监听端口一致。
内容的提问来源于stack exchange,提问作者kozmo
相关产品推荐
相关产品推荐

