英文:
Docker image executing golang executable: exec /usr/local/go/bin/go: exec format error
问题
我理解我需要指定一个go
可执行文件的目标平台,如果它打算在另一台机器上运行。我正在使用搭载 M1 芯片的苹果机器构建一个 Docker 镜像:
Dockerfile
FROM --platform=linux/amd64 golang:alpine AS build
WORKDIR /
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o .
FROM --platform=linux/amd64 scratch
WORKDIR /app
COPY --from=build /foo /foo
CMD ["./foo"]
这似乎可以工作,因为在构建后检查容器输出:
"Architecture": "amd64",
"Os": "linux"
但是,当我现在使用 docker-compose
在 Linux 服务器上启动镜像时,我收到一个错误:exec /usr/local/go/bin/go: exec format error
docker-compose.yml
foo:
environment:
- PORT=${PORT}
image: docker.io/name/foo
platform: linux/amd64
ports:
- "8000:8000"
restart: always
我对 Docker 还不太熟悉,所以我猜我在这里漏掉了一些非常明显的东西。
英文:
I understand that I need to specify the target platform of a go
executable if it is supposed to run on another machine. I'm building a docker image on an apple machine with the M1 chip:
Dockerfile
FROM --platform=linux/amd64 golang:alpine AS build
WORKDIR /
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o .
FROM --platform=linux/amd64 scratch
WORKDIR /app
COPY --from=build /foo /foo
CMD ["./foo"]
This appears to work because inspecting the container after build outputs
"Architecture": "amd64",
"Os": "linux"
But when I now start the image on a linux server using docker-compose
, I get an error: exec /usr/local/go/bin/go: exec format error
docker-compose.yml
foo:
environment:
- PORT=${PORT}
image: docker.io/name/foo
platform: linux/amd64
ports:
- "8000:8000"
restart: always
I'm pretty new to docker, so I guess I'm missing something quite obvious here.
答案1
得分: 1
首先,我可以确认您已成功构建了一个amd64二进制文件,所以这不是一个关于go
的问题。
如果我在一个amd64的Linux系统上运行您的镜像,我没有遇到您报告的错误。给定以下的docker-compose.yaml
文件:
foo:
environment:
- PORT=${PORT}
image: docker.io/chedched/foo
platform: linux/amd64
ports:
- "8000:8000"
restart: always
当运行docker-compose up
时,我看到以下错误信息:
ERROR: for images_foo_1 Cannot start service foo: failed to create shim task:
OCI runtime create failed: runc create failed: unable to start container
process: exec: "./foo": stat ./foo: no such file or directory: unknown
这是因为您设置了WORKDIR /app
,这使得app
成为您镜像中的当前工作目录,但是您将二进制文件安装为/foo
。您需要做以下更改之一:
-
将您的
CMD
更改为引用正确的位置:CMD ["/foo"]
或者...
-
将二进制文件安装到
/app
中:COPY --from=build /foo ./foo
通过进行上述任何更改,镜像将按预期运行。
英文:
First, I can confirm that you have successfully built an amd64 binary, so this isn't a go
question.
If I run your image (on an amd64 linux system), I don't get the same error that you've reported. Given this docker-compose.yaml
:
foo:
environment:
- PORT=${PORT}
image: docker.io/chedched/foo
platform: linux/amd64
ports:
- "8000:8000"
restart: always
When running docker-compose up
, I see:
ERROR: for images_foo_1 Cannot start service foo: failed to create shim task:
OCI runtime create failed: runc create failed: unable to start container
process: exec: "./foo": stat ./foo: no such file or directory: unknown
And this happens because you've set WORKDIR /app
, which makes app
the current working directory in your image, but you've installed your binary as /foo
. You need to either:
-
Change your
CMD
to reference the correct location:CMD ["/foo"]
Or...
-
Install the binary in
/app
:COPY --from=build /foo ./foo
With either of those changes, the image runs as expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论