Docker执行报错:CMD/ENTRYPOINT命令未找到——Golang API容器问题
问题原因
你的问题核心在于docker-compose的卷挂载覆盖了镜像中编译好的可执行文件:
- 构建镜像时,你在
/app目录下编译生成了executable文件,并且通过RUN指令确认了它的存在和可执行权限。 - 但启动容器时,
docker-compose里的- ./goapp:/app将宿主机的goapp目录挂载到了容器的/app目录,直接覆盖了镜像中原本包含executable的/app目录,导致容器内的/app变成了宿主机的代码目录,自然找不到编译好的可执行文件。
解决步骤
1. 移除不必要的宿主机代码挂载
修改docker-compose.yml,删除- ./goapp:/app这条卷挂载配置:
version: '3.3' services: # db... goapp: build: context: ./ dockerfile: ./docker/go/Dockerfile_prod environment: - SECRET=${SECRET} - PORT=3000 - GO_ENV=production - GIN_MODE=release - MYSQL_HOST=${MYSQL_HOST} - MYSQL_PORT=${MYSQL_PORT} - MYSQL_USER=${MYSQL_USER} - MYSQL_PASSWORD=${MYSQL_PASSWORD} - MYSQL_DATABASE=${MYSQL_DATABASE} - SMTP_HOST=${SMTP_HOST} - SMTP_USER=${SMTP_USER} - SMTP_PASSWORD=${SMTP_PASSWORD} - SENTRY_DSN=${SENTRY_DSN} ports: - 3000:3000 volumes: # 只保留数据挂载,移除代码目录挂载 - ./data/goapp:/app/data depends_on: db: condition: service_healthy
2. (可选)优化Dockerfile为多阶段构建
生产环境建议使用多阶段构建,减小镜像体积,同时避免编译依赖残留:
# 编译阶段 FROM golang:1.20-alpine AS builder WORKDIR /app COPY goapp/ . RUN go mod download # 编译为静态链接二进制,避免alpine缺少依赖问题 RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /app/executable . # 运行阶段 FROM alpine:latest WORKDIR /app # 从编译阶段复制可执行文件 COPY --from=builder /app/executable . # 确认文件存在 RUN [ -f /app/executable -a -x /app/executable ] CMD ["/app/executable"]
注:添加
CGO_ENABLED=0编译静态链接二进制,避免alpine系统中缺少glibc导致的执行错误(如果你的代码用到CGO则需要调整)。
3. 重新构建并启动容器
执行以下命令重新构建镜像并启动容器:
docker-compose -f <你的docker-compose文件路径> build --no-cache docker-compose -f <你的docker-compose文件路径> up -d
内容的提问来源于stack exchange,提问作者sjiamnocna
相关产品推荐
相关产品推荐

