运行dockerfile时出现“bash: No such file or directory”的错误。

huangapple go评论87阅读模式
英文:

bash: No such file or directory when running a dockerfile

问题

我正在尝试从一个名为dockerfile和一个名为docker-compose的文件中运行一个容器,它们的内容如下所示 -

docker-compose.yml

build:
      context: .
      dockerfile: docker/Dockerfile
      target: go-container
    entrypoint: bash -c "./main"

Dockerfile的内容如下 -

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ENV GOPATH /gopath
ENV PATH $GOPATH/bin:$PATH
WORKDIR /gopath/src/project

ADD go.mod go.sum ./
RUN go mod download -x
RUN go build -o main cmd/main.go


FROM scratch as another_container
COPY --from=go-container /gopath/src/project/main .
ENTRYPOINT ["./main"]

运行docker-compose时,我遇到了以下错误 -

bash: line 1: ./main: No such file or directory
ERROR: 127

这里发生了什么?我不知道如何调试它,所以任何帮助都将不胜感激!

英文:

I'm trying to run a container from a dockerfile and a docker-compose file which look like this -

docker-compose.yml

build:
      context: .
      dockerfile: docker/Dockerfile
      target: go-container
    entrypoint: bash -c "./main"

the Dockerfile looks like this -

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ENV GOPATH /gopath
ENV PATH $GOPATH/bin:$PATH
WORKDIR /gopath/src/project

ADD go.mod go.sum ./
RUN go mod download -x
RUN go build -o main cmd/main.go


FROM scratch as another_container
COPY --from=go-container /gopath/src/project/main .
ENTRYPOINT ["./main"]

On running the docker-compose, I get an error like this -

bash: line 1: ./main: No such file or directory
ERROR: 127

What is happening here? I don't know how to debug it so any help is appreciated!

答案1

得分: 3

从零开始作为另一个容器

你正在使用一个FROM语句,它会用一个基于镜像的新容器替换当前容器。在这种情况下,你使用的是FROM scratch,它是一个空容器。

由于你没有使用COPY --from从前一个阶段复制编译好的文件,所以./main文件丢失,因此你的应用程序无法正常工作。

请参考这里了解多阶段构建Go应用程序的示例。

英文:
FROM scratch as another_container

You're using a FROM statement, which replaces the current container with a new container based on an image. In this case, you're doing it FROM scratch, which is a container with nothing in it.

Since you didn't use COPY --from to copy the compiled file from the previous stage, the file ./main is missing, so your application won't work.

See here for a multistage Go build example.

答案2

得分: 1

Docker的scratch镜像不包含诸如bash之类的二进制文件,基本上是一个空的上下文。然后,FROM scratch as another_container指令会删除之前的层;在这种情况下,./main文件被排除在外。

你可以使用另一个最小化的镜像,比如FROM busybox as another_container,来执行./main二进制文件。

例如:

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ADD go.mod go.sum ./ 
RUN go mod download -x
RUN go build -o main cmd/main.go
FROM busybox as another_container
COPY --from=go-container ./main /main
ENTRYPOINT ["./main"]

完整示例:

docker-compose.yaml

version: "3.9"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
      target: go-container
    entrypoint: bash -c "./main"

Dockerfile

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ENV GOPATH /gopath
ENV PATH $GOPATH/bin:$PATH
WORKDIR /gopath/src/project

ADD go.mod go.sum main.go ./
RUN go mod download -x
RUN go build -o main main.go

FROM busybox as another_container
COPY --from=go-container /gopath/src/project/main .

ENTRYPOINT ["./main"]

main.go

package main

import "fmt"

func main() {
	fmt.Println("Created with vim-go")
}

使用以下命令执行:docker compose up

docker compose up
[+] Running 2/2
 ⠿ Network delete_default  Created                                                                                                                                                                                                       0.0s
 ⠿ Container delete-web-1  Created                                                                                                                                                                                                       0.0s
Attaching to delete-web-1
delete-web-1  | vim-go
delete-web-1 exited with code 0
英文:

Docker scratch doesn't have binaries such as bash, basically it's an empty context. The FROM scratch as another_container instruction then removes previous layers; in this case ./main file is excluded.

You could use another minimal image, ie FROM busybox as another_container, to execute the ./main binary.

ie:

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ADD go.mod go.sum ./
RUN go mod download -x
RUN go build -o main cmd/main.go
FROM busybox as another_container
COPY --from=go-container ./main /main
ENTRYPOINT ["./main"]

Full example:

docker-compose.yaml

version: "3.9"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
      target: go-container
    entrypoint: bash -c "./main"

Dockerfile

ARG GO_VERSION=1.17
FROM golang:$GO_VERSION as go-container
ENV GOPATH /gopath
ENV PATH $GOPATH/bin:$PATH
WORKDIR /gopath/src/project

ADD go.mod go.sum main.go ./
RUN go mod download -x
RUN go build -o main main.go

FROM busybox as another_container
COPY --from=go-container /gopath/src/project/main .

ENTRYPOINT ["./main"]

main.go

package main

import "fmt"

func main() {
	fmt.Println("Created with vim-go")
}

Execute with: docker compose up

docker compose up
[+] Running 2/2
 ⠿ Network delete_default  Created                                                                                                                                                                                                       0.0s
 ⠿ Container delete-web-1  Created                                                                                                                                                                                                       0.0s
Attaching to delete-web-1
delete-web-1  | vim-go
delete-web-1 exited with code 0

huangapple
  • 本文由 发表于 2022年8月17日 23:47:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/73391394.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定