使用Docker-Compose运行Go可执行文件报错:找不到./main文件,求排查
Go API Docker容器化启动失败:找不到./main可执行文件
问题详情
我用Go开发了一个简单的Rest API,希望通过Docker进行容器化部署。相关配置文件如下:
Dockerfile
FROM golang:1.19 # Port to expose ENV PORT=8080 WORKDIR /go/src/app # Install libvips RUN apt-get update && apt-get install -y libvips-dev # Copy go.mod and go.sum COPY go.mod go.sum ./ # Install go dependencies RUN go mod download # Set PKG_CONFIG_PATH for libvips ENV PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig RUN pkg-config --libs vips # Copy the source code COPY . . # Uncomment to build the app # Build the app RUN go build -o main . # Expose the port EXPOSE 8080 # Run the app CMD ["./main"]
docker-compose.yml
services: app: build: context: . dockerfile: Dockerfile container_name: backend command: ./main ports: - "3000:8080" volumes: - .:/go/src/app
之前该配置可正常运行,但最近启动失败,报错:
Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./main": stat ./main: no such file or directory: unknown
我怀疑可执行文件未在工作目录生成,但已使用相对路径构建命令,不确定问题原因。
问题原因及解决办法
核心原因:本地目录挂载覆盖容器内构建产物
你的docker-compose配置了volumes: - .:/go/src/app,这会将本地项目目录直接挂载到容器的工作目录。容器启动时,/go/src/app内的内容会被本地文件完全替换——而你本地大概率没有main可执行文件(因为go build是在容器构建阶段执行的,产物仅存在于镜像中,不在本地),因此容器找不到./main。
之前能运行可能是因为当时本地恰好生成了main文件,后续该文件被删除或清理后就出现了错误。
解决方案
方案1:移除本地目录挂载(推荐)
容器化部署的最佳实践是将应用构建到镜像内,无需挂载本地目录。修改docker-compose.yml,删除volumes相关配置:
services: app: build: context: . dockerfile: Dockerfile container_name: backend ports: - "3000:8080" # 移除以下两行 # volumes: # - .:/go/src/app
之后重新构建镜像并启动容器:
docker-compose down && docker-compose build && docker-compose up -d
方案2:本地提前构建可执行文件(仅用于开发调试)
如果是开发阶段需要热重载代码,可在本地执行go build -o main .生成可执行文件,这样挂载本地目录后容器就能找到./main。但此方式不符合容器化设计理念,且跨系统构建的可执行文件可能与Linux容器不兼容,不推荐用于生产环境。
额外检查
确认Dockerfile中的RUN go build -o main .未被注释(从提供的内容看该命令已生效),构建阶段会在镜像的/go/src/app目录生成main文件,只要不被挂载覆盖即可正常运行。
内容的提问来源于stack exchange,提问作者marco
相关产品推荐
相关产品推荐

